From 76926159194e180003aa78de97e5f287bf4325a5 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 15 Apr 2024 20:07:41 +0200 Subject: Adding upstream version 2.7.6. Signed-off-by: Daniel Baumann --- .gitlab-ci.yml | 25 + .pre-commit-config.yaml | 25 + AUTHORS | 7 + COPYING.GPL | 340 +++ Dockerfile | 11 + README.md | 49 + TODO | 4 + apt/__init__.py | 40 + apt/auth.py | 311 +++ apt/cache.py | 1004 +++++++ apt/cdrom.py | 91 + apt/debfile.py | 861 ++++++ apt/package.py | 1559 +++++++++++ apt/progress/__init__.py | 28 + apt/progress/base.py | 332 +++ apt/progress/text.py | 294 ++ apt/py.typed | 0 apt/utils.py | 100 + aptsources/__init__.py | 6 + aptsources/_deb822.py | 144 + aptsources/distinfo.py | 415 +++ aptsources/distro.py | 648 +++++ aptsources/sourceslist.py | 1083 ++++++++ data/templates/Blankon.info.in | 370 +++ data/templates/Blankon.mirrors | 17 + data/templates/Debian.info.in | 119 + data/templates/Debian.mirrors | 394 +++ data/templates/Kali.info.in | 32 + data/templates/Kali.mirrors | 2 + data/templates/README.templates | 59 + data/templates/Tanglu.info.in | 42 + data/templates/Tanglu.mirrors | 3 + data/templates/Ubuntu.info.in | 223 ++ data/templates/Ubuntu.mirrors | 665 +++++ data/templates/gNewSense.info.in | 55 + data/templates/gNewSense.mirrors | 489 ++++ doc/Makefile | 79 + doc/client-example.cc | 68 + doc/examples/acquire.py | 80 + doc/examples/action.py | 116 + doc/examples/all_deps.py | 37 + doc/examples/architecture.py | 12 + doc/examples/build-deps-old.py | 74 + doc/examples/build-deps.py | 58 + doc/examples/cdrom.py | 24 + doc/examples/checkstate.py | 37 + doc/examples/config.py | 60 + doc/examples/configisc.py | 49 + doc/examples/deb_inspect.py | 61 + doc/examples/depcache.py | 109 + doc/examples/dependant-pkgs.py | 38 + doc/examples/desc.py | 25 + doc/examples/indexfile.py | 22 + doc/examples/inst.py | 47 + doc/examples/metaindex.py | 16 + doc/examples/print_uris.py | 10 + doc/examples/progress.py | 118 + doc/examples/recommends.py | 37 + doc/examples/records.py | 16 + doc/examples/sources.py | 21 + doc/examples/tagfile.py | 8 + doc/examples/update.py | 14 + doc/examples/versiontest.py | 54 + doc/source/c++/api.rst | 858 ++++++ doc/source/c++/embedding.rst | 34 + doc/source/c++/index.rst | 8 + doc/source/conf.py | 245 ++ doc/source/contents.rst | 19 + doc/source/examples/apt-cdrom.py | 79 + doc/source/examples/cache-packages.py | 23 + doc/source/examples/cache-pkgfile.py | 30 + doc/source/examples/dpkg-contents.py | 68 + doc/source/examples/dpkg-extract.py | 27 + doc/source/examples/dpkg-info.py | 22 + doc/source/examples/missing-deps.py | 59 + doc/source/examples/update-print-uris.py | 24 + doc/source/library/apt.cache.rst | 83 + doc/source/library/apt.cdrom.rst | 7 + doc/source/library/apt.debfile.rst | 39 + doc/source/library/apt.package.rst | 122 + doc/source/library/apt.progress.base.rst | 335 +++ doc/source/library/apt.progress.text.rst | 21 + doc/source/library/apt_inst.rst | 323 +++ doc/source/library/apt_pkg.rst | 2904 ++++++++++++++++++++ doc/source/library/aptsources.distinfo.rst | 11 + doc/source/library/aptsources.distro.rst | 11 + doc/source/library/aptsources.sourceslist.rst | 11 + doc/source/library/index.rst | 35 + doc/source/templates/indexcontent.html | 50 + doc/source/templates/layout.html | 4 + doc/source/tutorials/apt-cdrom.rst | 156 ++ doc/source/tutorials/apt-get.rst | 46 + doc/source/tutorials/contributing.rst | 315 +++ doc/source/tutorials/index.rst | 8 + doc/source/whatsnew/0.7.100.rst | 211 ++ doc/source/whatsnew/0.8.0.rst | 38 + doc/source/whatsnew/0.9.4.rst | 17 + doc/source/whatsnew/1.0.rst | 75 + doc/source/whatsnew/1.1.rst | 28 + doc/source/whatsnew/1.4.rst | 16 + doc/source/whatsnew/1.6.rst | 26 + doc/source/whatsnew/1.7.rst | 42 + doc/source/whatsnew/1.8.rst | 8 + doc/source/whatsnew/2.0.rst | 37 + doc/source/whatsnew/2.1.rst | 7 + doc/source/whatsnew/index.rst | 9 + mypy.ini | 2 + po/POTFILES.in | 8 + po/ar.po | 622 +++++ po/be.po | 638 +++++ po/bg.po | 680 +++++ po/bn.po | 671 +++++ po/ca.po | 679 +++++ po/cs.po | 660 +++++ po/csb.po | 621 +++++ po/da.po | 637 +++++ po/de.po | 645 +++++ po/el.po | 638 +++++ po/en_AU.po | 660 +++++ po/en_CA.po | 681 +++++ po/eo.po | 649 +++++ po/es.po | 663 +++++ po/fi.po | 639 +++++ po/fr.po | 652 +++++ po/gl.po | 661 +++++ po/he.po | 667 +++++ po/hr.po | 660 +++++ po/hu.po | 647 +++++ po/id.po | 638 +++++ po/it.po | 662 +++++ po/ja.po | 640 +++++ po/ka.po | 661 +++++ po/ko.po | 659 +++++ po/ku.po | 660 +++++ po/lt.po | 664 +++++ po/lv.po | 627 +++++ po/mk.po | 681 +++++ po/nb.po | 683 +++++ po/ne.po | 682 +++++ po/nl.po | 639 +++++ po/oc.po | 661 +++++ po/pl.po | 644 +++++ po/pt.po | 657 +++++ po/pt_BR.po | 648 +++++ po/python-apt.pot | 365 +++ po/ro.po | 663 +++++ po/ru.po | 665 +++++ po/sk.po | 638 +++++ po/sl.po | 649 +++++ po/sq.po | 623 +++++ po/sr.po | 648 +++++ po/sv.po | 662 +++++ po/th.po | 659 +++++ po/tl.po | 639 +++++ po/tr.po | 659 +++++ po/uk.po | 635 +++++ po/vi.po | 683 +++++ po/zh_CN.po | 656 +++++ po/zh_HK.po | 633 +++++ po/zh_TW.po | 653 +++++ pre-build.sh | 18 + python/acquire-item.cc | 356 +++ python/acquire.cc | 424 +++ python/apt_instmodule.cc | 87 + python/apt_instmodule.h | 29 + python/apt_pkgmodule.cc | 1117 ++++++++ python/apt_pkgmodule.h | 214 ++ python/arfile.cc | 744 +++++ python/cache.cc | 1600 +++++++++++ python/cachegroup.cc | 188 ++ python/cdrom.cc | 139 + python/configuration.cc | 613 +++++ python/depcache.cc | 1169 ++++++++ python/generic.cc | 122 + python/generic.h | 336 +++ python/hashes.cc | 135 + python/hashstring.cc | 182 ++ python/hashstringlist.cc | 220 ++ python/indexfile.cc | 130 + python/lock.cc | 268 ++ python/metaindex.cc | 117 + python/orderlist.cc | 317 +++ python/pkgmanager.cc | 375 +++ python/pkgrecords.cc | 280 ++ python/pkgrecords.h | 10 + python/pkgsrcrecords.cc | 438 +++ python/policy.cc | 243 ++ python/progress.cc | 473 ++++ python/progress.h | 120 + python/python-apt-helpers.cc | 69 + python/python-apt.h | 368 +++ python/sourcelist.cc | 170 ++ python/string.cc | 142 + python/tag.cc | 1063 +++++++ python/tarfile.cc | 521 ++++ setup.cfg | 5 + setup.py | 159 ++ tests/__init__.py | 1 + tests/data/aptsources/lsb-release | 4 + tests/data/aptsources/os-release | 10 + tests/data/aptsources/sources.list | 10 + .../sources.list.d.testDistribution/main.sources | 74 + .../sources.list.d.testDuplication/main.sources | 10 + tests/data/aptsources/sources.list.d/main.sources | 32 + .../data/aptsources/sources.list.testDistribution | 14 + tests/data/aptsources/sources.list.testDuplication | 2 + tests/data/aptsources_ports/sources.list | 52 + tests/data/fake-packages/Packages | 21 + tests/data/fake-packages/Packages.gz | Bin 0 -> 555 bytes tests/data/hashsums/hashsum_test.data | 1 + tests/data/hashsums/hashsum_test_with_zero.data | Bin 0 -> 7 bytes tests/data/misc/foo_Release | 492 ++++ tests/data/tagfile/history.1.log.gz | Bin 0 -> 270 bytes tests/data/tagfile/history.log | 15 + tests/data/test-provides/etc/apt/sources.list | 1 + ..._ubuntu_dists_oneiric_main_binary-i386_Packages | 75 + tests/data/test-provides/var/lib/dpkg/status | 0 tests/data/test-repo/Packages.gz | Bin 0 -> 675 bytes tests/data/test-repo2/Packages.gz | Bin 0 -> 675 bytes tests/data/test-signed-usable-repo/key.gpg.base64 | 62 + tests/data/test-signed-usable-repo/seckey.asc | 158 ++ tests/data/test-signed-usable-repo/signed/Packages | 26 + tests/data/test-signed-usable-repo/signed/Release | 17 + .../test-signed-usable-repo/signed/Release.gpg | 14 + tests/data/test-signed-usable-repo/signed/Sources | 21 + .../signed/signed-not-usable_1.0.dsc | 11 + .../signed/signed-not-usable_1.0_all.deb | 1 + .../signed/signed-usable_1.0.dsc | 11 + .../signed/signed-usable_1.0_all.deb | 1 + .../data/test-signed-usable-repo/unsigned/Packages | 26 + .../data/test-signed-usable-repo/unsigned/Release | 17 + .../data/test-signed-usable-repo/unsigned/Sources | 22 + .../unsigned/unsigned-not-usable_1.0.dsc | 11 + .../unsigned/unsigned-unusable_1.0_all.deb | 1 + .../unsigned/unsigned-usable_1.0.dsc | 11 + .../unsigned/unsigned-usable_1.0_all.deb | 1 + tests/data/test-source-repo/Sources | 25 + tests/data/test_debs/data-tar-broken.deb | Bin 0 -> 626 bytes tests/data/test_debs/data-tar-xz.deb | Bin 0 -> 680 bytes tests/data/test_debs/data-tar.deb | Bin 0 -> 20672 bytes tests/data/test_debs/etc/apt/sources.list | 1 + tests/data/test_debs/gdebi-test1.deb | Bin 0 -> 934 bytes tests/data/test_debs/gdebi-test10.deb | Bin 0 -> 614 bytes tests/data/test_debs/gdebi-test11.deb | Bin 0 -> 634 bytes tests/data/test_debs/gdebi-test12.deb | Bin 0 -> 966 bytes tests/data/test_debs/gdebi-test13.deb | Bin 0 -> 720 bytes tests/data/test_debs/gdebi-test2.deb | Bin 0 -> 554 bytes tests/data/test_debs/gdebi-test3.deb | Bin 0 -> 570 bytes tests/data/test_debs/gdebi-test4.deb | Bin 0 -> 2306 bytes tests/data/test_debs/gdebi-test5.deb | Bin 0 -> 2306 bytes tests/data/test_debs/gdebi-test6.deb | Bin 0 -> 600 bytes tests/data/test_debs/gdebi-test7.deb | Bin 0 -> 578 bytes tests/data/test_debs/gdebi-test8.deb | Bin 0 -> 598 bytes tests/data/test_debs/gdebi-test9.deb | Bin 0 -> 586 bytes tests/data/test_debs/hello_2.5-1.dsc | 34 + .../test_debs/impossible-build-depends_2.5-1.dsc | 33 + .../test_debs/large-package-content_1.0_all.deb | Bin 0 -> 781546 bytes tests/data/test_debs/multiarch-test1_i386.deb | Bin 0 -> 978 bytes .../test_debs/testdep-allowed-any_1.0-1_i386.deb | Bin 0 -> 1128 bytes .../test_debs/testdep-same-arch_1.0-1_i386.deb | Bin 0 -> 1236 bytes tests/data/test_debs/utf8-package_1.0-1_all.deb | Bin 0 -> 1150 bytes ...ubuntu_dists_maverick_main_binary-i386_Packages | 31 + tests/data/test_debs/var/lib/dpkg/status | 92 + tests/fakeroot-apt-key | 2 + tests/helper_install_progress_run.py | 15 + tests/old/__init__.py | 11 + tests/old/apt-test.py | 27 + tests/old/cache.py | 51 + tests/old/depcache.py | 57 + tests/old/lock.py | 47 + tests/old/memleak.py | 45 + tests/old/pkgproblemresolver.py | 71 + tests/old/pkgrecords.py | 41 + tests/old/pkgsrcrecords.py | 31 + tests/old/refcount.py | 54 + tests/old/test_enhances.py | 16 + tests/test_all.py | 63 + tests/test_apt_cache.py | 400 +++ tests/test_aptsources.py | 1573 +++++++++++ tests/test_aptsources_deb822.py | 63 + tests/test_aptsources_ports.py | 41 + tests/test_auth.py | 314 +++ tests/test_cache_invocation.py | 31 + tests/test_configuration.py | 31 + tests/test_cve_2020_27351.py | 149 + tests/test_debfile.py | 192 ++ tests/test_debfile_multiarch.py | 63 + tests/test_deps.py | 142 + tests/test_group.py | 31 + tests/test_hashes.py | 206 ++ tests/test_hashsums.py | 106 + tests/test_install_progress_exec.py | 43 + tests/test_large_file.py | 25 + tests/test_lfs.py | 19 + tests/test_lp659438.py | 80 + tests/test_paths.py | 158 ++ tests/test_pep484.py | 28 + tests/test_policy.py | 70 + tests/test_progress.py | 56 + tests/test_pyflakes.py | 43 + tests/test_signed_usable.py | 403 +++ tests/test_size_to_str.py | 104 + tests/test_sourcerecords.py | 129 + tests/test_tagfile.py | 186 ++ tests/test_utils.py | 74 + tests/testcommon.py | 30 + typehinting/apt_inst.pyi | 37 + typehinting/apt_pkg.pyi | 390 +++ utils/expand_info.py | 11 + utils/get_debian_mirrors.py | 47 + utils/get_ubuntu_mirrors_from_lp.py | 56 + utils/mirrortest | 108 + 312 files changed, 71716 insertions(+) create mode 100644 .gitlab-ci.yml create mode 100644 .pre-commit-config.yaml create mode 100644 AUTHORS create mode 100644 COPYING.GPL create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 TODO create mode 100644 apt/__init__.py create mode 100644 apt/auth.py create mode 100644 apt/cache.py create mode 100644 apt/cdrom.py create mode 100644 apt/debfile.py create mode 100644 apt/package.py create mode 100644 apt/progress/__init__.py create mode 100644 apt/progress/base.py create mode 100644 apt/progress/text.py create mode 100644 apt/py.typed create mode 100644 apt/utils.py create mode 100644 aptsources/__init__.py create mode 100644 aptsources/_deb822.py create mode 100644 aptsources/distinfo.py create mode 100644 aptsources/distro.py create mode 100644 aptsources/sourceslist.py create mode 100644 data/templates/Blankon.info.in create mode 100644 data/templates/Blankon.mirrors create mode 100644 data/templates/Debian.info.in create mode 100644 data/templates/Debian.mirrors create mode 100644 data/templates/Kali.info.in create mode 100644 data/templates/Kali.mirrors create mode 100644 data/templates/README.templates create mode 100644 data/templates/Tanglu.info.in create mode 100644 data/templates/Tanglu.mirrors create mode 100644 data/templates/Ubuntu.info.in create mode 100644 data/templates/Ubuntu.mirrors create mode 100644 data/templates/gNewSense.info.in create mode 100644 data/templates/gNewSense.mirrors create mode 100644 doc/Makefile create mode 100644 doc/client-example.cc create mode 100644 doc/examples/acquire.py create mode 100644 doc/examples/action.py create mode 100644 doc/examples/all_deps.py create mode 100644 doc/examples/architecture.py create mode 100755 doc/examples/build-deps-old.py create mode 100755 doc/examples/build-deps.py create mode 100644 doc/examples/cdrom.py create mode 100755 doc/examples/checkstate.py create mode 100755 doc/examples/config.py create mode 100755 doc/examples/configisc.py create mode 100755 doc/examples/deb_inspect.py create mode 100644 doc/examples/depcache.py create mode 100755 doc/examples/dependant-pkgs.py create mode 100644 doc/examples/desc.py create mode 100644 doc/examples/indexfile.py create mode 100644 doc/examples/inst.py create mode 100644 doc/examples/metaindex.py create mode 100755 doc/examples/print_uris.py create mode 100644 doc/examples/progress.py create mode 100755 doc/examples/recommends.py create mode 100755 doc/examples/records.py create mode 100644 doc/examples/sources.py create mode 100755 doc/examples/tagfile.py create mode 100755 doc/examples/update.py create mode 100755 doc/examples/versiontest.py create mode 100644 doc/source/c++/api.rst create mode 100644 doc/source/c++/embedding.rst create mode 100644 doc/source/c++/index.rst create mode 100644 doc/source/conf.py create mode 100644 doc/source/contents.rst create mode 100644 doc/source/examples/apt-cdrom.py create mode 100755 doc/source/examples/cache-packages.py create mode 100755 doc/source/examples/cache-pkgfile.py create mode 100755 doc/source/examples/dpkg-contents.py create mode 100755 doc/source/examples/dpkg-extract.py create mode 100755 doc/source/examples/dpkg-info.py create mode 100755 doc/source/examples/missing-deps.py create mode 100755 doc/source/examples/update-print-uris.py create mode 100644 doc/source/library/apt.cache.rst create mode 100644 doc/source/library/apt.cdrom.rst create mode 100644 doc/source/library/apt.debfile.rst create mode 100644 doc/source/library/apt.package.rst create mode 100644 doc/source/library/apt.progress.base.rst create mode 100644 doc/source/library/apt.progress.text.rst create mode 100644 doc/source/library/apt_inst.rst create mode 100644 doc/source/library/apt_pkg.rst create mode 100644 doc/source/library/aptsources.distinfo.rst create mode 100644 doc/source/library/aptsources.distro.rst create mode 100644 doc/source/library/aptsources.sourceslist.rst create mode 100644 doc/source/library/index.rst create mode 100644 doc/source/templates/indexcontent.html create mode 100644 doc/source/templates/layout.html create mode 100644 doc/source/tutorials/apt-cdrom.rst create mode 100644 doc/source/tutorials/apt-get.rst create mode 100644 doc/source/tutorials/contributing.rst create mode 100644 doc/source/tutorials/index.rst create mode 100644 doc/source/whatsnew/0.7.100.rst create mode 100644 doc/source/whatsnew/0.8.0.rst create mode 100644 doc/source/whatsnew/0.9.4.rst create mode 100644 doc/source/whatsnew/1.0.rst create mode 100644 doc/source/whatsnew/1.1.rst create mode 100644 doc/source/whatsnew/1.4.rst create mode 100644 doc/source/whatsnew/1.6.rst create mode 100644 doc/source/whatsnew/1.7.rst create mode 100644 doc/source/whatsnew/1.8.rst create mode 100644 doc/source/whatsnew/2.0.rst create mode 100644 doc/source/whatsnew/2.1.rst create mode 100644 doc/source/whatsnew/index.rst create mode 100644 mypy.ini create mode 100644 po/POTFILES.in create mode 100644 po/ar.po create mode 100644 po/be.po create mode 100644 po/bg.po create mode 100644 po/bn.po create mode 100644 po/ca.po create mode 100644 po/cs.po create mode 100644 po/csb.po create mode 100644 po/da.po create mode 100644 po/de.po create mode 100644 po/el.po create mode 100644 po/en_AU.po create mode 100644 po/en_CA.po create mode 100644 po/eo.po create mode 100644 po/es.po create mode 100644 po/fi.po create mode 100644 po/fr.po create mode 100644 po/gl.po create mode 100644 po/he.po create mode 100644 po/hr.po create mode 100644 po/hu.po create mode 100644 po/id.po create mode 100644 po/it.po create mode 100644 po/ja.po create mode 100644 po/ka.po create mode 100644 po/ko.po create mode 100644 po/ku.po create mode 100644 po/lt.po create mode 100644 po/lv.po create mode 100644 po/mk.po create mode 100644 po/nb.po create mode 100644 po/ne.po create mode 100644 po/nl.po create mode 100644 po/oc.po create mode 100644 po/pl.po create mode 100644 po/pt.po create mode 100644 po/pt_BR.po create mode 100644 po/python-apt.pot create mode 100644 po/ro.po create mode 100644 po/ru.po create mode 100644 po/sk.po create mode 100644 po/sl.po create mode 100644 po/sq.po create mode 100644 po/sr.po create mode 100644 po/sv.po create mode 100644 po/th.po create mode 100644 po/tl.po create mode 100644 po/tr.po create mode 100644 po/uk.po create mode 100644 po/vi.po create mode 100644 po/zh_CN.po create mode 100644 po/zh_HK.po create mode 100644 po/zh_TW.po create mode 100755 pre-build.sh create mode 100644 python/acquire-item.cc create mode 100644 python/acquire.cc create mode 100644 python/apt_instmodule.cc create mode 100644 python/apt_instmodule.h create mode 100644 python/apt_pkgmodule.cc create mode 100644 python/apt_pkgmodule.h create mode 100644 python/arfile.cc create mode 100644 python/cache.cc create mode 100644 python/cachegroup.cc create mode 100644 python/cdrom.cc create mode 100644 python/configuration.cc create mode 100644 python/depcache.cc create mode 100644 python/generic.cc create mode 100644 python/generic.h create mode 100644 python/hashes.cc create mode 100644 python/hashstring.cc create mode 100644 python/hashstringlist.cc create mode 100644 python/indexfile.cc create mode 100644 python/lock.cc create mode 100644 python/metaindex.cc create mode 100644 python/orderlist.cc create mode 100644 python/pkgmanager.cc create mode 100644 python/pkgrecords.cc create mode 100644 python/pkgrecords.h create mode 100644 python/pkgsrcrecords.cc create mode 100644 python/policy.cc create mode 100644 python/progress.cc create mode 100644 python/progress.h create mode 100644 python/python-apt-helpers.cc create mode 100644 python/python-apt.h create mode 100644 python/sourcelist.cc create mode 100644 python/string.cc create mode 100644 python/tag.cc create mode 100644 python/tarfile.cc create mode 100644 setup.cfg create mode 100644 setup.py create mode 100644 tests/__init__.py create mode 100644 tests/data/aptsources/lsb-release create mode 100644 tests/data/aptsources/os-release create mode 100644 tests/data/aptsources/sources.list create mode 100644 tests/data/aptsources/sources.list.d.testDistribution/main.sources create mode 100644 tests/data/aptsources/sources.list.d.testDuplication/main.sources create mode 100644 tests/data/aptsources/sources.list.d/main.sources create mode 100644 tests/data/aptsources/sources.list.testDistribution create mode 100644 tests/data/aptsources/sources.list.testDuplication create mode 100644 tests/data/aptsources_ports/sources.list create mode 100644 tests/data/fake-packages/Packages create mode 100644 tests/data/fake-packages/Packages.gz create mode 100644 tests/data/hashsums/hashsum_test.data create mode 100644 tests/data/hashsums/hashsum_test_with_zero.data create mode 100644 tests/data/misc/foo_Release create mode 100644 tests/data/tagfile/history.1.log.gz create mode 100644 tests/data/tagfile/history.log create mode 100644 tests/data/test-provides/etc/apt/sources.list create mode 100644 tests/data/test-provides/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_oneiric_main_binary-i386_Packages create mode 100644 tests/data/test-provides/var/lib/dpkg/status create mode 100644 tests/data/test-repo/Packages.gz create mode 100644 tests/data/test-repo2/Packages.gz create mode 100644 tests/data/test-signed-usable-repo/key.gpg.base64 create mode 100644 tests/data/test-signed-usable-repo/seckey.asc create mode 100644 tests/data/test-signed-usable-repo/signed/Packages create mode 100644 tests/data/test-signed-usable-repo/signed/Release create mode 100644 tests/data/test-signed-usable-repo/signed/Release.gpg create mode 100644 tests/data/test-signed-usable-repo/signed/Sources create mode 100644 tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0.dsc create mode 100644 tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0_all.deb create mode 100644 tests/data/test-signed-usable-repo/signed/signed-usable_1.0.dsc create mode 100644 tests/data/test-signed-usable-repo/signed/signed-usable_1.0_all.deb create mode 100644 tests/data/test-signed-usable-repo/unsigned/Packages create mode 100644 tests/data/test-signed-usable-repo/unsigned/Release create mode 100644 tests/data/test-signed-usable-repo/unsigned/Sources create mode 100644 tests/data/test-signed-usable-repo/unsigned/unsigned-not-usable_1.0.dsc create mode 100644 tests/data/test-signed-usable-repo/unsigned/unsigned-unusable_1.0_all.deb create mode 100644 tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0.dsc create mode 100644 tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0_all.deb create mode 100644 tests/data/test-source-repo/Sources create mode 100644 tests/data/test_debs/data-tar-broken.deb create mode 100644 tests/data/test_debs/data-tar-xz.deb create mode 100644 tests/data/test_debs/data-tar.deb create mode 100644 tests/data/test_debs/etc/apt/sources.list create mode 100644 tests/data/test_debs/gdebi-test1.deb create mode 100644 tests/data/test_debs/gdebi-test10.deb create mode 100644 tests/data/test_debs/gdebi-test11.deb create mode 100644 tests/data/test_debs/gdebi-test12.deb create mode 100644 tests/data/test_debs/gdebi-test13.deb create mode 100644 tests/data/test_debs/gdebi-test2.deb create mode 100644 tests/data/test_debs/gdebi-test3.deb create mode 100644 tests/data/test_debs/gdebi-test4.deb create mode 100644 tests/data/test_debs/gdebi-test5.deb create mode 100644 tests/data/test_debs/gdebi-test6.deb create mode 100644 tests/data/test_debs/gdebi-test7.deb create mode 100644 tests/data/test_debs/gdebi-test8.deb create mode 100644 tests/data/test_debs/gdebi-test9.deb create mode 100644 tests/data/test_debs/hello_2.5-1.dsc create mode 100644 tests/data/test_debs/impossible-build-depends_2.5-1.dsc create mode 100644 tests/data/test_debs/large-package-content_1.0_all.deb create mode 100644 tests/data/test_debs/multiarch-test1_i386.deb create mode 100644 tests/data/test_debs/testdep-allowed-any_1.0-1_i386.deb create mode 100644 tests/data/test_debs/testdep-same-arch_1.0-1_i386.deb create mode 100644 tests/data/test_debs/utf8-package_1.0-1_all.deb create mode 100644 tests/data/test_debs/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_maverick_main_binary-i386_Packages create mode 100644 tests/data/test_debs/var/lib/dpkg/status create mode 100755 tests/fakeroot-apt-key create mode 100755 tests/helper_install_progress_run.py create mode 100644 tests/old/__init__.py create mode 100644 tests/old/apt-test.py create mode 100644 tests/old/cache.py create mode 100644 tests/old/depcache.py create mode 100644 tests/old/lock.py create mode 100644 tests/old/memleak.py create mode 100644 tests/old/pkgproblemresolver.py create mode 100644 tests/old/pkgrecords.py create mode 100644 tests/old/pkgsrcrecords.py create mode 100755 tests/old/refcount.py create mode 100644 tests/old/test_enhances.py create mode 100644 tests/test_all.py create mode 100644 tests/test_apt_cache.py create mode 100644 tests/test_aptsources.py create mode 100755 tests/test_aptsources_deb822.py create mode 100644 tests/test_aptsources_ports.py create mode 100644 tests/test_auth.py create mode 100644 tests/test_cache_invocation.py create mode 100644 tests/test_configuration.py create mode 100644 tests/test_cve_2020_27351.py create mode 100644 tests/test_debfile.py create mode 100644 tests/test_debfile_multiarch.py create mode 100644 tests/test_deps.py create mode 100644 tests/test_group.py create mode 100644 tests/test_hashes.py create mode 100644 tests/test_hashsums.py create mode 100644 tests/test_install_progress_exec.py create mode 100644 tests/test_large_file.py create mode 100644 tests/test_lfs.py create mode 100644 tests/test_lp659438.py create mode 100644 tests/test_paths.py create mode 100644 tests/test_pep484.py create mode 100644 tests/test_policy.py create mode 100644 tests/test_progress.py create mode 100644 tests/test_pyflakes.py create mode 100644 tests/test_signed_usable.py create mode 100644 tests/test_size_to_str.py create mode 100644 tests/test_sourcerecords.py create mode 100644 tests/test_tagfile.py create mode 100644 tests/test_utils.py create mode 100644 tests/testcommon.py create mode 100644 typehinting/apt_inst.pyi create mode 100644 typehinting/apt_pkg.pyi create mode 100755 utils/expand_info.py create mode 100755 utils/get_debian_mirrors.py create mode 100755 utils/get_ubuntu_mirrors_from_lp.py create mode 100755 utils/mirrortest diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..876e324 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,25 @@ +image: debian:unstable +variables: + DEBIAN_FRONTEND: noninteractive +pre-commit: + script: + - apt update + - apt install -q -y pre-commit git + - pre-commit run -a --show-diff-on-failure +test: + script: + - apt update + - apt build-dep -q -y ./ + - dpkg-buildpackage + artifacts: + paths: + - build/sphinx/html/ +pages: + stage: deploy + script: + - mv build/sphinx/html/ public + artifacts: + paths: + - public + rules: + - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..ddd6c4b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,25 @@ +repos: + - repo: https://github.com/asottile/pyupgrade + rev: v3.15.0 + hooks: + - id: pyupgrade + args: [--py311-plus] + - repo: https://github.com/pycqa/isort + rev: 5.13.2 + hooks: + - id: isort + args: ["--profile", "black", "--filter-files"] + - repo: https://github.com/PyCQA/autoflake + rev: v2.2.1 + hooks: + - id: autoflake + - repo: https://github.com/psf/black + rev: 23.12.1 + hooks: + - id: black + - repo: https://github.com/pre-commit/mirrors-mypy + rev: 'v1.8.0' + hooks: + - id: mypy + args: [--strict] + exclude: tests/|aptsources/(distro.py|sourceslist.py)|doc/|utils/|setup.py diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..1ed949c --- /dev/null +++ b/AUTHORS @@ -0,0 +1,7 @@ +jgg Jason Gunthorpe +mdz Matt Zimmerman +mvo Michael Vogt +Michiel Sikkes +Sebastian Heinlein +Sean Wheller +Julian Andres Klode diff --git a/COPYING.GPL b/COPYING.GPL new file mode 100644 index 0000000..60549be --- /dev/null +++ b/COPYING.GPL @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..53b9b3c --- /dev/null +++ b/Dockerfile @@ -0,0 +1,11 @@ +FROM debian:testing +COPY . /tmp +WORKDIR /tmp +RUN sed -i s#://deb.debian.org#://cdn-fastly.deb.debian.org# /etc/apt/sources.list \ + && apt-get update \ + && adduser --home /home/travis travis --quiet --disabled-login --gecos "" --uid 1000 \ + && env DEBIAN_FRONTEND=noninteractive apt-get build-dep -y /tmp \ + && env DEBIAN_FRONTEND=noninteractive apt-get install -y ccache python3-pip \ + && python3 -m pip install -U mypy \ + && rm -r /tmp/* \ + && apt-get clean diff --git a/README.md b/README.md new file mode 100644 index 0000000..a3ea8aa --- /dev/null +++ b/README.md @@ -0,0 +1,49 @@ +# Python-apt is a wrapper to use features of apt from python. + +It contains the following modules: + +## C++ Wrapper: + +* apt_pkg - access to libapt-pkg (wrapper to the lowlevel c++ code) +* apt_inst - access to libapt-inst (wrapper to the lowlevel c++ code) + +## Python module: + +* apt - high level python interface build on top of apt_pkg, apt_inst +* aptsources - high level manipulation of sources.list + + +# Development + +## Building + +To build python-apt run: +``` +$ python setup.py build +``` +You may need to install the build-dependencies via: +``` +$ sudo apt build-dep ./ +``` +first. + +## Running the tests + +Run the tests with: +``` +$ python tests/test_all.py +$ python3 tests/test_all.py +``` + +## Running mypy: + +To check if the "apt" python module is mypy clean, run: +``` +$ MYPYPATH=./typehinting/ mypy ./apt +``` + +To use the annotation with your source code, run: +``` +$ MYPYPATH=/usr/lib/python3/dist-packages/apt mypy ./my-program +``` +(adjust from python3 to python2.7 if you run there). diff --git a/TODO b/TODO new file mode 100644 index 0000000..a08a28a --- /dev/null +++ b/TODO @@ -0,0 +1,4 @@ +* aptsources: + - make the distro detection in sources.list more clever by using the + origin informaton to avoid adding full uris to (unofficial/internal) + mirrors diff --git a/apt/__init__.py b/apt/__init__.py new file mode 100644 index 0000000..f22c9a0 --- /dev/null +++ b/apt/__init__.py @@ -0,0 +1,40 @@ +# Copyright (c) 2005-2009 Canonical +# +# Author: Michael Vogt +# +# 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 +# import the core of apt_pkg +"""High-Level Interface for working with apt.""" +import apt_pkg + +from apt.cache import Cache as Cache +from apt.cache import ProblemResolver as ProblemResolver + +# import some fancy classes +from apt.package import Package as Package +from apt.package import Version as Version + +Cache # pyflakes +ProblemResolver # pyflakes +Version # pyflakes +from apt.cdrom import Cdrom as Cdrom + +# init the package system, but do not re-initialize config +if "APT" not in apt_pkg.config: + apt_pkg.init_config() +apt_pkg.init_system() + +__all__ = ["Cache", "Cdrom", "Package"] diff --git a/apt/auth.py b/apt/auth.py new file mode 100644 index 0000000..6d50616 --- /dev/null +++ b/apt/auth.py @@ -0,0 +1,311 @@ +#!/usr/bin/python3 +# auth - authentication key management +# +# Copyright (c) 2004 Canonical +# Copyright (c) 2012 Sebastian Heinlein +# +# Author: Michael Vogt +# Sebastian Heinlein +# +# 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 +"""Handle GnuPG keys used to trust signed repositories.""" + +import errno +import os +import os.path +import shutil +import subprocess +import sys +import tempfile + +import apt_pkg +from apt_pkg import gettext as _ + + +class AptKeyError(Exception): + pass + + +class AptKeyIDTooShortError(AptKeyError): + """Internal class do not rely on it.""" + + +class TrustedKey: + + """Represents a trusted key.""" + + def __init__(self, name: str, keyid: str, date: str) -> None: + self.raw_name = name + # Allow to translated some known keys + self.name = _(name) + self.keyid = keyid + self.date = date + + def __str__(self) -> str: + return f"{self.name}\n{self.keyid} {self.date}" + + +def _call_apt_key_script(*args: str, **kwargs: str | None) -> str: + """Run the apt-key script with the given arguments.""" + conf = None + cmd = [apt_pkg.config.find_file("Dir::Bin::Apt-Key", "/usr/bin/apt-key")] + cmd.extend(args) + env = os.environ.copy() + env["LANG"] = "C" + env["APT_KEY_DONT_WARN_ON_DANGEROUS_USAGE"] = "1" + try: + if apt_pkg.config.find_dir("Dir") != "/": + # If the key is to be installed into a chroot we have to export the + # configuration from the chroot to the apt-key script by using + # a temporary APT_CONFIG file. The apt-key script uses apt-config + # shell internally + conf = tempfile.NamedTemporaryFile(prefix="apt-key", suffix=".conf") + conf.write(apt_pkg.config.dump().encode("UTF-8")) + conf.flush() + env["APT_CONFIG"] = conf.name + proc = subprocess.Popen( + cmd, + env=env, + universal_newlines=True, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + + stdin = kwargs.get("stdin", None) + + output, stderr = proc.communicate(stdin) # type: str, str + + if proc.returncode: + raise AptKeyError( + "The apt-key script failed with return code %s:\n" + "%s\n" + "stdout: %s\n" + "stderr: %s" % (proc.returncode, " ".join(cmd), output, stderr) + ) + elif stderr: + sys.stderr.write(stderr) # Forward stderr + + return output.strip() + finally: + if conf is not None: + conf.close() + + +def add_key_from_file(filename: str) -> None: + """Import a GnuPG key file to trust repositores signed by it. + + Keyword arguments: + filename -- the absolute path to the public GnuPG key file + """ + if not os.path.abspath(filename): + raise AptKeyError("An absolute path is required: %s" % filename) + if not os.access(filename, os.R_OK): + raise AptKeyError("Key file cannot be accessed: %s" % filename) + _call_apt_key_script("add", filename) + + +def add_key_from_keyserver(keyid: str, keyserver: str) -> None: + """Import a GnuPG key file to trust repositores signed by it. + + Keyword arguments: + keyid -- the long keyid (fingerprint) of the key, e.g. + A1BD8E9D78F7FE5C3E65D8AF8B48AD6246925553 + keyserver -- the URL or hostname of the key server + """ + tmp_keyring_dir = tempfile.mkdtemp() + try: + _add_key_from_keyserver(keyid, keyserver, tmp_keyring_dir) + except Exception: + raise + finally: + # We are racing with gpg when removing sockets, so ignore + # failure to delete non-existing files. + def onerror( + func: object, path: str, exc_info: tuple[type, Exception, object] + ) -> None: + if isinstance(exc_info[1], OSError) and exc_info[1].errno == errno.ENOENT: + return + raise + + shutil.rmtree(tmp_keyring_dir, onerror=onerror) + + +def _add_key_from_keyserver(keyid: str, keyserver: str, tmp_keyring_dir: str) -> None: + if len(keyid.replace(" ", "").replace("0x", "")) < (160 / 4): + raise AptKeyIDTooShortError("Only fingerprints (v4, 160bit) are supported") + # create a temp keyring dir + tmp_secret_keyring = os.path.join(tmp_keyring_dir, "secring.gpg") + tmp_keyring = os.path.join(tmp_keyring_dir, "pubring.gpg") + # default options for gpg + gpg_default_options = [ + "gpg", + "--no-default-keyring", + "--no-options", + "--homedir", + tmp_keyring_dir, + ] + # download the key to a temp keyring first + res = subprocess.call( + gpg_default_options + + [ + "--secret-keyring", + tmp_secret_keyring, + "--keyring", + tmp_keyring, + "--keyserver", + keyserver, + "--recv", + keyid, + ] + ) + if res != 0: + raise AptKeyError(f"recv from '{keyserver}' failed for '{keyid}'") + # FIXME: + # - with gnupg 1.4.18 the downloaded key is actually checked(!), + # i.e. gnupg will not import anything that the server sends + # into the keyring, so the below checks are now redundant *if* + # gnupg 1.4.18 is used + + # now export again using the long key id (to ensure that there is + # really only this one key in our keyring) and not someone MITM us + tmp_export_keyring = os.path.join(tmp_keyring_dir, "export-keyring.gpg") + res = subprocess.call( + gpg_default_options + + [ + "--keyring", + tmp_keyring, + "--output", + tmp_export_keyring, + "--export", + keyid, + ] + ) + if res != 0: + raise AptKeyError("export of '%s' failed", keyid) + # now verify the fingerprint, this is probably redundant as we + # exported by the fingerprint in the previous command but its + # still good paranoia + output = subprocess.Popen( + gpg_default_options + + [ + "--keyring", + tmp_export_keyring, + "--fingerprint", + "--batch", + "--fixed-list-mode", + "--with-colons", + ], + stdout=subprocess.PIPE, + universal_newlines=True, + ).communicate()[0] + got_fingerprint = None + for line in output.splitlines(): + if line.startswith("fpr:"): + got_fingerprint = line.split(":")[9] + # stop after the first to ensure no subkey trickery + break + # strip the leading "0x" is there is one and uppercase (as this is + # what gnupg is using) + signing_key_fingerprint = keyid.replace("0x", "").upper() + if got_fingerprint != signing_key_fingerprint: + # make the error match what gnupg >= 1.4.18 will output when + # it checks the key itself before importing it + raise AptKeyError( + f"recv from '{keyserver}' failed for '{signing_key_fingerprint}'" + ) + # finally add it + add_key_from_file(tmp_export_keyring) + + +def add_key(content: str) -> None: + """Import a GnuPG key to trust repositores signed by it. + + Keyword arguments: + content -- the content of the GnuPG public key + """ + _call_apt_key_script("adv", "--quiet", "--batch", "--import", "-", stdin=content) + + +def remove_key(fingerprint: str) -> None: + """Remove a GnuPG key to no longer trust repositores signed by it. + + Keyword arguments: + fingerprint -- the fingerprint identifying the key + """ + _call_apt_key_script("rm", fingerprint) + + +def export_key(fingerprint: str) -> str: + """Return the GnuPG key in text format. + + Keyword arguments: + fingerprint -- the fingerprint identifying the key + """ + return _call_apt_key_script("export", fingerprint) + + +def update() -> str: + """Update the local keyring with the archive keyring and remove from + the local keyring the archive keys which are no longer valid. The + archive keyring is shipped in the archive-keyring package of your + distribution, e.g. the debian-archive-keyring package in Debian. + """ + return _call_apt_key_script("update") + + +def net_update() -> str: + """Work similar to the update command above, but get the archive + keyring from an URI instead and validate it against a master key. + This requires an installed wget(1) and an APT build configured to + have a server to fetch from and a master keyring to validate. APT + in Debian does not support this command and relies on update + instead, but Ubuntu's APT does. + """ + return _call_apt_key_script("net-update") + + +def list_keys() -> list[TrustedKey]: + """Returns a list of TrustedKey instances for each key which is + used to trust repositories. + """ + # The output of `apt-key list` is difficult to parse since the + # --with-colons parameter isn't user + output = _call_apt_key_script( + "adv", "--with-colons", "--batch", "--fixed-list-mode", "--list-keys" + ) + res = [] + for line in output.split("\n"): + fields = line.split(":") + if fields[0] == "pub": + keyid = fields[4] + if fields[0] == "uid": + uid = fields[9] + creation_date = fields[5] + key = TrustedKey(uid, keyid, creation_date) + res.append(key) + return res + + +if __name__ == "__main__": + # Add some known keys we would like to see translated so that they get + # picked up by gettext + lambda: _("Ubuntu Archive Automatic Signing Key ") + lambda: _("Ubuntu CD Image Automatic Signing Key ") + + apt_pkg.init() + for trusted_key in list_keys(): + print(trusted_key) diff --git a/apt/cache.py b/apt/cache.py new file mode 100644 index 0000000..cf78026 --- /dev/null +++ b/apt/cache.py @@ -0,0 +1,1004 @@ +# cache.py - apt cache abstraction +# +# Copyright (c) 2005-2009 Canonical +# +# Author: Michael Vogt +# +# 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 + +from __future__ import annotations + +import fnmatch +import os +import warnings +import weakref +from collections.abc import Callable, Iterator, KeysView +from typing import Any, cast + +import apt_pkg + +import apt.progress.text +from apt.package import Package, Version +from apt.progress.base import AcquireProgress, InstallProgress, OpProgress + + +class FetchCancelledException(IOError): + """Exception that is thrown when the user cancels a fetch operation.""" + + +class FetchFailedException(IOError): + """Exception that is thrown when fetching fails.""" + + +class UntrustedException(FetchFailedException): + """Exception that is thrown when fetching fails for trust reasons""" + + +class LockFailedException(IOError): + """Exception that is thrown when locking fails.""" + + +class CacheClosedException(Exception): + """Exception that is thrown when the cache is used after close().""" + + +class _WrappedLock: + """Wraps an apt_pkg.FileLock to raise LockFailedException. + + Initialized using a directory path.""" + + def __init__(self, path: str) -> None: + self._path = path + self._lock = apt_pkg.FileLock(os.path.join(path, "lock")) + + def __enter__(self) -> None: + try: + return self._lock.__enter__() + except apt_pkg.Error as e: + raise LockFailedException( + ("Failed to lock directory %s: %s") % (self._path, e) + ) + + def __exit__(self, typ: object, value: object, traceback: object) -> None: + return self._lock.__exit__(typ, value, traceback) + + +class Cache: + """Dictionary-like package cache. + + The APT cache file contains a hash table mapping names of binary + packages to their metadata. A Cache object is the in-core + representation of the same. It provides access to APTs idea of the + list of available packages. + + The cache can be used like a mapping from package names to Package + objects (although only getting items is supported). + + Keyword arguments: + progress -- a OpProgress object, + rootdir -- an alternative root directory. if that is given the system + sources.list and system lists/files are not read, only file relative + to the given rootdir, + memonly -- build the cache in memory only. + + + .. versionchanged:: 1.0 + + The cache now supports package names with special architecture + qualifiers such as :all and :native. It does not export them + in :meth:`keys()`, though, to keep :meth:`keys()` a unique set. + """ + + def __init__( + self, + progress: OpProgress | None = None, + rootdir: str | None = None, + memonly: bool = False, + ) -> None: + self._cache: apt_pkg.Cache = cast(apt_pkg.Cache, None) + self._depcache: apt_pkg.DepCache = cast(apt_pkg.DepCache, None) + self._records: apt_pkg.PackageRecords = cast( + apt_pkg.PackageRecords, None + ) # noqa + self._list: apt_pkg.SourceList = cast(apt_pkg.SourceList, None) + self._callbacks: dict[str, list[Callable[..., None] | str]] = {} # noqa + self._callbacks2: dict[ + str, list[tuple[Callable[..., Any], tuple[Any, ...], dict[Any, Any]]] + ] = {} # noqa + self._weakref: weakref.WeakValueDictionary[ + str, apt.Package + ] = weakref.WeakValueDictionary() # noqa + self._weakversions: weakref.WeakSet[Version] = weakref.WeakSet() # noqa + self._changes_count = -1 + self._sorted_set: list[str] | None = None + + self.connect("cache_post_open", "_inc_changes_count") + self.connect("cache_post_change", "_inc_changes_count") + if memonly: + # force apt to build its caches in memory + apt_pkg.config.set("Dir::Cache::pkgcache", "") + if rootdir: + rootdir = os.path.abspath(rootdir) + if os.path.exists(rootdir + "/etc/apt/apt.conf"): + apt_pkg.read_config_file(apt_pkg.config, rootdir + "/etc/apt/apt.conf") + if os.path.isdir(rootdir + "/etc/apt/apt.conf.d"): + apt_pkg.read_config_dir(apt_pkg.config, rootdir + "/etc/apt/apt.conf.d") + apt_pkg.config.set("Dir", rootdir) + apt_pkg.config.set("Dir::State::status", rootdir + "/var/lib/dpkg/status") + # also set dpkg to the rootdir path so that its called for the + # --print-foreign-architectures call + apt_pkg.config.set( + "Dir::bin::dpkg", os.path.join(rootdir, "usr", "bin", "dpkg") + ) + # create required dirs/files when run with special rootdir + # automatically + self._check_and_create_required_dirs(rootdir) + # Call InitSystem so the change to Dir::State::Status is actually + # recognized (LP: #320665) + apt_pkg.init_system() + + # Prepare a lock object (context manager for archive lock) + archive_dir = apt_pkg.config.find_dir("Dir::Cache::Archives") + self._archive_lock = _WrappedLock(archive_dir) + + self.open(progress) + + def fix_broken(self) -> None: + """Fix broken packages.""" + self._depcache.fix_broken() + + def _inc_changes_count(self) -> None: + """Increase the number of changes""" + self._changes_count += 1 + + def _check_and_create_required_dirs(self, rootdir: str) -> None: + """ + check if the required apt directories/files are there and if + not create them + """ + files = [ + "/var/lib/dpkg/status", + "/etc/apt/sources.list", + ] + dirs = [ + "/var/lib/dpkg", + "/etc/apt/", + "/var/cache/apt/archives/partial", + "/var/lib/apt/lists/partial", + ] + for d in dirs: + if not os.path.exists(rootdir + d): + # print "creating: ", rootdir + d + os.makedirs(rootdir + d) + for f in files: + if not os.path.exists(rootdir + f): + open(rootdir + f, "w").close() + + def _run_callbacks(self, name: str) -> None: + """internal helper to run a callback""" + if name in self._callbacks: + for callback in self._callbacks[name]: + if callback == "_inc_changes_count": + self._inc_changes_count() + else: + callback() # type: ignore + + if name in self._callbacks2: + for callback, args, kwds in self._callbacks2[name]: + callback(self, *args, **kwds) + + def open(self, progress: OpProgress | None = None) -> None: + """Open the package cache, after that it can be used like + a dictionary + """ + if progress is None: + progress = apt.progress.base.OpProgress() + # close old cache on (re)open + self.close() + self.op_progress = progress + self._run_callbacks("cache_pre_open") + + self._cache = apt_pkg.Cache(progress) + self._depcache = apt_pkg.DepCache(self._cache) + self._records = apt_pkg.PackageRecords(self._cache) + self._list = apt_pkg.SourceList() + self._list.read_main_list() + self._sorted_set = None + self.__remap() + + self._have_multi_arch = len(apt_pkg.get_architectures()) > 1 + + progress.done() + self._run_callbacks("cache_post_open") + + def __remap(self) -> None: + """Called after cache reopen() to relocate to new cache. + + Relocate objects like packages and versions from the old + underlying cache to the new one. + """ + for key in list(self._weakref.keys()): + try: + pkg = self._weakref[key] + except KeyError: + continue + + try: + pkg._pkg = self._cache[pkg._pkg.name, pkg._pkg.architecture] + except LookupError: + del self._weakref[key] + + for ver in list(self._weakversions): + # Package has been reseated above, reseat version + for v in ver.package._pkg.version_list: + # Requirements as in debListParser::SameVersion + if ( + v.hash == ver._cand.hash + and (v.size == 0 or ver._cand.size == 0 or v.size == ver._cand.size) + and v.multi_arch == ver._cand.multi_arch + and v.ver_str == ver._cand.ver_str + ): + ver._cand = v + break + else: + self._weakversions.remove(ver) + + def close(self) -> None: + """Close the package cache""" + # explicitely free the FDs that _records has open + del self._records + self._records = cast(apt_pkg.PackageRecords, None) + + def __enter__(self) -> Cache: + """Enter the with statement""" + return self + + def __exit__(self, exc_type: object, exc_value: object, traceback: object) -> None: + """Exit the with statement""" + self.close() + + def __getitem__(self, key: object) -> Package: + """look like a dictionary (get key)""" + try: + key = str(key) + rawpkg = self._cache[key] + except KeyError: + raise KeyError("The cache has no package named %r" % key) + + # It might be excluded due to not having a version or something + if not self.__is_real_pkg(rawpkg): + raise KeyError("The cache has no package named %r" % key) + + pkg = self._rawpkg_to_pkg(rawpkg) + + return pkg + + def get(self, key: object, default: object = None) -> Any: + """Return *self*[*key*] or *default* if *key* not in *self*. + + .. versionadded:: 1.1 + """ + try: + return self[key] + except KeyError: + return default + + def _rawpkg_to_pkg(self, rawpkg: apt_pkg.Package) -> Package: + """Returns the apt.Package object for an apt_pkg.Package object. + + .. versionadded:: 1.0.0 + """ + fullname = rawpkg.get_fullname(pretty=True) + + return self._weakref.setdefault(fullname, Package(self, rawpkg)) + + def __iter__(self) -> Iterator[Package]: + # We iterate sorted over package names here. With this we read the + # package lists linearly if we need to access the package records, + # instead of having to do thousands of random seeks; the latter + # is disastrous if we use compressed package indexes, and slower than + # necessary for uncompressed indexes. + for pkgname in self.keys(): + pkg = Package(self, self._cache[pkgname]) + yield self._weakref.setdefault(pkgname, pkg) + + def __is_real_pkg(self, rawpkg: apt_pkg.Package) -> bool: + """Check if the apt_pkg.Package provided is a real package.""" + return rawpkg.has_versions + + def has_key(self, key: object) -> bool: + return key in self + + def __contains__(self, key: object) -> bool: + try: + return self.__is_real_pkg(self._cache[str(key)]) + except KeyError: + return False + + def __len__(self) -> int: + return len(self.keys()) + + def keys(self) -> list[str]: + if self._sorted_set is None: + self._sorted_set = sorted( + p.get_fullname(pretty=True) + for p in self._cache.packages + if self.__is_real_pkg(p) + ) + return list(self._sorted_set) # We need a copy here, caller may modify + + def get_changes(self) -> list[Package]: + """Get the marked changes""" + changes = [] + marked_keep = self._depcache.marked_keep + for rawpkg in self._cache.packages: + if not marked_keep(rawpkg): + changes.append(self._rawpkg_to_pkg(rawpkg)) + return changes + + def upgrade(self, dist_upgrade: bool = False) -> None: + """Upgrade all packages. + + If the parameter *dist_upgrade* is True, new dependencies will be + installed as well (and conflicting packages may be removed). The + default value is False. + """ + self.cache_pre_change() + self._depcache.upgrade(dist_upgrade) + self.cache_post_change() + + @property + def required_download(self) -> int: + """Get the size of the packages that are required to download.""" + if self._records is None: + raise CacheClosedException("Cache object used after close() called") + pm = apt_pkg.PackageManager(self._depcache) + fetcher = apt_pkg.Acquire() + pm.get_archives(fetcher, self._list, self._records) + return fetcher.fetch_needed + + @property + def required_space(self) -> int: + """Get the size of the additional required space on the fs.""" + return self._depcache.usr_size + + @property + def req_reinstall_pkgs(self) -> set[str]: + """Return the packages not downloadable packages in reqreinst state.""" + reqreinst = set() + get_candidate_ver = self._depcache.get_candidate_ver + states = frozenset( + (apt_pkg.INSTSTATE_REINSTREQ, apt_pkg.INSTSTATE_HOLD_REINSTREQ) + ) + for pkg in self._cache.packages: + cand = get_candidate_ver(pkg) + if cand and not cand.downloadable and pkg.inst_state in states: + reqreinst.add(pkg.get_fullname(pretty=True)) + return reqreinst + + def _run_fetcher( + self, fetcher: apt_pkg.Acquire, allow_unauthenticated: bool | None + ) -> int: + if allow_unauthenticated is None: + allow_unauthenticated = apt_pkg.config.find_b( + "APT::Get::" "AllowUnauthenticated", False + ) + + untrusted = [item for item in fetcher.items if not item.is_trusted] + if untrusted and not allow_unauthenticated: + raise UntrustedException( + "Untrusted packages:\n%s" % "\n".join(i.desc_uri for i in untrusted) + ) + + # do the actual fetching + res = fetcher.run() + + # now check the result (this is the code from apt-get.cc) + failed = False + err_msg = "" + for item in fetcher.items: + if item.status == item.STAT_DONE: + continue + if item.STAT_IDLE: + continue + err_msg += f"Failed to fetch {item.desc_uri} {item.error_text}\n" + failed = True + + # we raise a exception if the download failed or it was cancelt + if res == fetcher.RESULT_CANCELLED: + raise FetchCancelledException(err_msg) + elif failed: + raise FetchFailedException(err_msg) + return res + + def _fetch_archives( + self, + fetcher: apt_pkg.Acquire, + pm: apt_pkg.PackageManager, + allow_unauthenticated: bool | None = None, + ) -> int: + """fetch the needed archives""" + if self._records is None: + raise CacheClosedException("Cache object used after close() called") + + # this may as well throw a SystemError exception + if not pm.get_archives(fetcher, self._list, self._records): + return False + + # now run the fetcher, throw exception if something fails to be + # fetched + return self._run_fetcher(fetcher, allow_unauthenticated) + + def fetch_archives( + self, + progress: AcquireProgress | None = None, + fetcher: apt_pkg.Acquire | None = None, + allow_unauthenticated: bool | None = None, + ) -> int: + """Fetch the archives for all packages marked for install/upgrade. + + You can specify either an :class:`apt.progress.base.AcquireProgress()` + object for the parameter *progress*, or specify an already + existing :class:`apt_pkg.Acquire` object for the parameter *fetcher*. + + The return value of the function is undefined. If an error occurred, + an exception of type :class:`FetchFailedException` or + :class:`FetchCancelledException` is raised. + + The keyword-only parameter *allow_unauthenticated* specifies whether + to allow unauthenticated downloads. If not specified, it defaults to + the configuration option `APT::Get::AllowUnauthenticated`. + + .. versionadded:: 0.8.0 + """ + if progress is not None and fetcher is not None: + raise ValueError("Takes a progress or a an Acquire object") + if progress is None: + progress = apt.progress.text.AcquireProgress() + if fetcher is None: + fetcher = apt_pkg.Acquire(progress) + + with self._archive_lock: + return self._fetch_archives( + fetcher, apt_pkg.PackageManager(self._depcache), allow_unauthenticated + ) + + def is_virtual_package(self, pkgname: str) -> bool: + """Return whether the package is a virtual package.""" + try: + pkg = self._cache[pkgname] + except KeyError: + return False + else: + return bool(pkg.has_provides and not pkg.has_versions) + + def get_providing_packages( + self, + pkgname: str, + candidate_only: bool = True, + include_nonvirtual: bool = False, + ) -> list[Package]: + """Return a list of all packages providing a package. + + Return a list of packages which provide the virtual package of the + specified name. + + If 'candidate_only' is False, return all packages with at + least one version providing the virtual package. Otherwise, + return only those packages where the candidate version + provides the virtual package. + + If 'include_nonvirtual' is True then it will search for all + packages providing pkgname, even if pkgname is not itself + a virtual pkg. + """ + + providers: set[Package] = set() + get_candidate_ver = self._depcache.get_candidate_ver + try: + vp = self._cache[pkgname] + if vp.has_versions and not include_nonvirtual: + return list(providers) + except KeyError: + return list(providers) + + for provides, providesver, version in vp.provides_list: + rawpkg = version.parent_pkg + if not candidate_only or (version == get_candidate_ver(rawpkg)): + providers.add(self._rawpkg_to_pkg(rawpkg)) + return list(providers) + + def update( + self, + fetch_progress: AcquireProgress | None = None, + pulse_interval: int = 0, + raise_on_error: bool = True, + sources_list: str | None = None, + ) -> int: + """Run the equivalent of apt-get update. + + You probably want to call open() afterwards, in order to utilise the + new cache. Otherwise, the old cache will be used which can lead to + strange bugs. + + The first parameter *fetch_progress* may be set to an instance of + apt.progress.FetchProgress, the default is apt.progress.FetchProgress() + . + sources_list -- Update a alternative sources.list than the default. + Note that the sources.list.d directory is ignored in this case + """ + with _WrappedLock(apt_pkg.config.find_dir("Dir::State::Lists")): + if sources_list: + old_sources_list = apt_pkg.config.find("Dir::Etc::sourcelist") + old_sources_list_d = apt_pkg.config.find("Dir::Etc::sourceparts") + old_cleanup = apt_pkg.config.find("APT::List-Cleanup") + apt_pkg.config.set( + "Dir::Etc::sourcelist", os.path.abspath(sources_list) + ) + apt_pkg.config.set("Dir::Etc::sourceparts", "xxx") + apt_pkg.config.set("APT::List-Cleanup", "0") + slist = apt_pkg.SourceList() + slist.read_main_list() + else: + slist = self._list + + try: + if fetch_progress is None: + fetch_progress = apt.progress.base.AcquireProgress() + try: + res = self._cache.update(fetch_progress, slist, pulse_interval) + except SystemError as e: + raise FetchFailedException(e) + if not res and raise_on_error: + raise FetchFailedException() + else: + return res + finally: + if sources_list: + apt_pkg.config.set("Dir::Etc::sourcelist", old_sources_list) + apt_pkg.config.set("Dir::Etc::sourceparts", old_sources_list_d) + apt_pkg.config.set("APT::List-Cleanup", old_cleanup) + + def install_archives( + self, pm: apt_pkg.PackageManager, install_progress: InstallProgress + ) -> int: + """ + The first parameter *pm* refers to an object returned by + apt_pkg.PackageManager(). + + The second parameter *install_progress* refers to an InstallProgress() + object of the module apt.progress. + + This releases a system lock in newer versions, if there is any, + and reestablishes it afterwards. + """ + # compat with older API + try: + install_progress.startUpdate() # type: ignore + except AttributeError: + install_progress.start_update() + + did_unlock = apt_pkg.pkgsystem_is_locked() + if did_unlock: + apt_pkg.pkgsystem_unlock_inner() + + try: + res = install_progress.run(pm) + finally: + if did_unlock: + apt_pkg.pkgsystem_lock_inner() + + try: + install_progress.finishUpdate() # type: ignore + except AttributeError: + install_progress.finish_update() + return res + + def commit( + self, + fetch_progress: AcquireProgress | None = None, + install_progress: InstallProgress | None = None, + allow_unauthenticated: bool | None = None, + ) -> bool: + """Apply the marked changes to the cache. + + The first parameter, *fetch_progress*, refers to a FetchProgress() + object as found in apt.progress, the default being + apt.progress.FetchProgress(). + + The second parameter, *install_progress*, is a + apt.progress.InstallProgress() object. + + The keyword-only parameter *allow_unauthenticated* specifies whether + to allow unauthenticated downloads. If not specified, it defaults to + the configuration option `APT::Get::AllowUnauthenticated`. + """ + # FIXME: + # use the new acquire/pkgmanager interface here, + # raise exceptions when a download or install fails + # and send proper error strings to the application. + # Current a failed download will just display "error" + # which is less than optimal! + + if fetch_progress is None: + fetch_progress = apt.progress.base.AcquireProgress() + if install_progress is None: + install_progress = apt.progress.base.InstallProgress() + + assert install_progress is not None + + with apt_pkg.SystemLock(): + pm = apt_pkg.PackageManager(self._depcache) + fetcher = apt_pkg.Acquire(fetch_progress) + with self._archive_lock: + while True: + # fetch archives first + res = self._fetch_archives(fetcher, pm, allow_unauthenticated) + + # then install + res = self.install_archives(pm, install_progress) + if res == pm.RESULT_COMPLETED: + break + elif res == pm.RESULT_FAILED: + raise SystemError("installArchives() failed") + elif res == pm.RESULT_INCOMPLETE: + pass + else: + raise SystemError( + "internal-error: unknown result " + "code from InstallArchives: %s" % res + ) + # reload the fetcher for media swaping + fetcher.shutdown() + return res == pm.RESULT_COMPLETED + + def clear(self) -> None: + """Unmark all changes""" + self._depcache.init() + + # cache changes + + def cache_post_change(self) -> None: + "called internally if the cache has changed, emit a signal then" + self._run_callbacks("cache_post_change") + + def cache_pre_change(self) -> None: + """called internally if the cache is about to change, emit + a signal then""" + self._run_callbacks("cache_pre_change") + + def connect(self, name: str, callback: Callable[..., None] | str) -> None: + """Connect to a signal. + + .. deprecated:: 1.0 + + Please use connect2() instead, as this function is very + likely to cause a memory leak. + """ + if callback != "_inc_changes_count": + warnings.warn( + "connect() likely causes a reference" " cycle, use connect2() instead", + RuntimeWarning, + 2, + ) + if name not in self._callbacks: + self._callbacks[name] = [] + self._callbacks[name].append(callback) + + def connect2( + self, name: str, callback: Callable[..., Any], *args: object, **kwds: object + ) -> None: + """Connect to a signal. + + The callback will be passed the cache as an argument, and + any arguments passed to this function. Make sure that, if you + pass a method of a class as your callback, your class does not + contain a reference to the cache. + + Cyclic references to the cache can cause issues if the Cache object + is replaced by a new one, because the cache keeps a lot of objects and + tens of open file descriptors. + + currently only used for cache_{post,pre}_{changed,open}. + + .. versionadded:: 1.0 + """ + if name not in self._callbacks2: + self._callbacks2[name] = [] + self._callbacks2[name].append((callback, args, kwds)) + + def actiongroup(self) -> apt_pkg.ActionGroup: + """Return an `ActionGroup` object for the current cache. + + Action groups can be used to speedup actions. The action group is + active as soon as it is created, and disabled when the object is + deleted or when release() is called. + + You can use the action group as a context manager, this is the + recommended way:: + + with cache.actiongroup(): + for package in my_selected_packages: + package.mark_install() + + This way, the action group is automatically released as soon as the + with statement block is left. It also has the benefit of making it + clear which parts of the code run with a action group and which + don't. + """ + return apt_pkg.ActionGroup(self._depcache) + + @property + def dpkg_journal_dirty(self) -> bool: + """Return True if the dpkg was interrupted + + All dpkg operations will fail until this is fixed, the action to + fix the system if dpkg got interrupted is to run + 'dpkg --configure -a' as root. + """ + dpkg_status_dir = os.path.dirname( + apt_pkg.config.find_file("Dir::State::status") + ) + for f in os.listdir(os.path.join(dpkg_status_dir, "updates")): + if fnmatch.fnmatch(f, "[0-9]*"): + return True + return False + + @property + def broken_count(self) -> int: + """Return the number of packages with broken dependencies.""" + return self._depcache.broken_count + + @property + def delete_count(self) -> int: + """Return the number of packages marked for deletion.""" + return self._depcache.del_count + + @property + def install_count(self) -> int: + """Return the number of packages marked for installation.""" + return self._depcache.inst_count + + @property + def keep_count(self) -> int: + """Return the number of packages marked as keep.""" + return self._depcache.keep_count + + +class ProblemResolver: + """Resolve problems due to dependencies and conflicts. + + The first argument 'cache' is an instance of apt.Cache. + """ + + def __init__(self, cache: Cache) -> None: + self._resolver = apt_pkg.ProblemResolver(cache._depcache) + self._cache = cache + + def clear(self, package: Package) -> None: + """Reset the package to the default state.""" + self._resolver.clear(package._pkg) + + def protect(self, package: Package) -> None: + """Protect a package so it won't be removed.""" + self._resolver.protect(package._pkg) + + def remove(self, package: Package) -> None: + """Mark a package for removal.""" + self._resolver.remove(package._pkg) + + def resolve(self) -> None: + """Resolve dependencies, try to remove packages where needed.""" + self._cache.cache_pre_change() + self._resolver.resolve() + self._cache.cache_post_change() + + def resolve_by_keep(self) -> None: + """Resolve dependencies, do not try to remove packages.""" + self._cache.cache_pre_change() + self._resolver.resolve_by_keep() + self._cache.cache_post_change() + + def keep_phased_updates(self) -> None: + """Keep back phased updates.""" + self._cache.cache_pre_change() + self._resolver.keep_phased_updates() + self._cache.cache_post_change() + + +# ----------------------------- experimental interface + + +class Filter: + """Filter base class""" + + def apply(self, pkg: Package) -> bool: + """Filter function, return True if the package matchs a + filter criteria and False otherwise + """ + return True + + +class MarkedChangesFilter(Filter): + """Filter that returns all marked changes""" + + def apply(self, pkg: Package) -> bool: + if pkg.marked_install or pkg.marked_delete or pkg.marked_upgrade: + return True + else: + return False + + +class InstalledFilter(Filter): + """Filter that returns all installed packages. + + .. versionadded:: 1.0.0 + """ + + def apply(self, pkg: Package) -> bool: + return pkg.is_installed + + +class _FilteredCacheHelper: + """Helper class for FilteredCache to break a reference cycle.""" + + def __init__(self, cache: Cache) -> None: + # Do not keep a reference to the cache, or you have a cycle! + + self._filtered: dict[str, bool] = {} + self._filters: list[Filter] = [] + cache.connect2("cache_post_change", self.filter_cache_post_change) + cache.connect2("cache_post_open", self.filter_cache_post_change) + + def _reapply_filter(self, cache: Cache) -> None: + "internal helper to refilter" + # Do not keep a reference to the cache, or you have a cycle! + self._filtered = {} + for pkg in cache: + for f in self._filters: + if f.apply(pkg): + self._filtered[pkg.name] = True + break + + def set_filter(self, filter: Filter) -> None: + """Set the current active filter.""" + self._filters = [] + self._filters.append(filter) + + def filter_cache_post_change(self, cache: Cache) -> None: + """Called internally if the cache changes, emit a signal then.""" + # Do not keep a reference to the cache, or you have a cycle! + self._reapply_filter(cache) + + +class FilteredCache: + """A package cache that is filtered. + + Can work on a existing cache or create a new one + """ + + def __init__( + self, cache: Cache | None = None, progress: OpProgress | None = None + ) -> None: + if cache is None: + self.cache = Cache(progress) + else: + self.cache = cache + self._helper = _FilteredCacheHelper(self.cache) + + def __len__(self) -> int: + return len(self._helper._filtered) + + def __getitem__(self, key: str) -> Package: + return self.cache[key] + + def __iter__(self) -> Iterator[Package]: + for pkgname in self._helper._filtered: + yield self.cache[pkgname] + + def keys(self) -> KeysView[str]: + return self._helper._filtered.keys() + + def has_key(self, key: object) -> bool: + return key in self + + def __contains__(self, key: object) -> bool: + try: + # Normalize package name for multi arch + return self.cache[key].name in self._helper._filtered + except KeyError: + return False + + def set_filter(self, filter: Filter) -> None: + """Set the current active filter.""" + self._helper.set_filter(filter) + self.cache.cache_post_change() + + def filter_cache_post_change(self) -> None: + """Called internally if the cache changes, emit a signal then.""" + self._helper.filter_cache_post_change(self.cache) + + def __getattr__(self, key: str) -> Any: + """we try to look exactly like a real cache.""" + return getattr(self.cache, key) + + +def cache_pre_changed(cache: Cache) -> None: + print("cache pre changed") + + +def cache_post_changed(cache: Cache) -> None: + print("cache post changed") + + +def _test() -> None: + """Internal test code.""" + print("Cache self test") + apt_pkg.init() + cache = Cache(apt.progress.text.OpProgress()) + cache.connect2("cache_pre_change", cache_pre_changed) + cache.connect2("cache_post_change", cache_post_changed) + print("aptitude" in cache) + pkg = cache["aptitude"] + print(pkg.name) + print(len(cache)) + + for pkgname in cache.keys(): + assert cache[pkgname].name == pkgname + + cache.upgrade() + changes = cache.get_changes() + print(len(changes)) + for pkg in changes: + assert pkg.name + + # see if fetching works + for dirname in ["/tmp/pytest", "/tmp/pytest/partial"]: + if not os.path.exists(dirname): + os.mkdir(dirname) + apt_pkg.config.set("Dir::Cache::Archives", "/tmp/pytest") + pm = apt_pkg.PackageManager(cache._depcache) + fetcher = apt_pkg.Acquire(apt.progress.text.AcquireProgress()) + cache._fetch_archives(fetcher, pm, None) + # sys.exit(1) + + print("Testing filtered cache (argument is old cache)") + filtered = FilteredCache(cache) + filtered.cache.connect2("cache_pre_change", cache_pre_changed) + filtered.cache.connect2("cache_post_change", cache_post_changed) + filtered.cache.upgrade() + filtered.set_filter(MarkedChangesFilter()) + print(len(filtered)) + for pkgname in filtered.keys(): + assert pkgname == filtered[pkgname].name + + print(len(filtered)) + + print("Testing filtered cache (no argument)") + filtered = FilteredCache(progress=apt.progress.base.OpProgress()) + filtered.cache.connect2("cache_pre_change", cache_pre_changed) + filtered.cache.connect2("cache_post_change", cache_post_changed) + filtered.cache.upgrade() + filtered.set_filter(MarkedChangesFilter()) + print(len(filtered)) + for pkgname in filtered.keys(): + assert pkgname == filtered[pkgname].name + + print(len(filtered)) + + +if __name__ == "__main__": + _test() diff --git a/apt/cdrom.py b/apt/cdrom.py new file mode 100644 index 0000000..dc15c5b --- /dev/null +++ b/apt/cdrom.py @@ -0,0 +1,91 @@ +# cdrom.py - CDROM handling +# +# Copyright (c) 2005-2009 Canonical +# Copyright (c) 2009 Julian Andres Klode +# +# Author: Michael Vogt +# +# 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 +"""Classes related to cdrom handling.""" +import glob + +import apt_pkg + +from apt.progress.base import CdromProgress + + +class Cdrom(apt_pkg.Cdrom): + """Support for apt-cdrom like features. + + This class has several optional parameters for initialisation, which may + be used to influence the behaviour of the object: + + The optional parameter `progress` is a CdromProgress() subclass, which will + ask for the correct cdrom, etc. If not specified or None, a CdromProgress() + object will be used. + + The optional parameter `mountpoint` may be used to specify an alternative + mountpoint. + + If the optional parameter `nomount` is True, the cdroms will not be + mounted. This is the default behaviour. + """ + + def __init__( + self, + progress: CdromProgress | None = None, + mountpoint: str | None = None, + nomount: bool = True, + ) -> None: + apt_pkg.Cdrom.__init__(self) + if progress is None: + self._progress = CdromProgress() + else: + self._progress = progress + # see if we have a alternative mountpoint + if mountpoint is not None: + apt_pkg.config.set("Acquire::cdrom::mount", mountpoint) + # do not mess with mount points by default + if nomount: + apt_pkg.config.set("APT::CDROM::NoMount", "true") + else: + apt_pkg.config.set("APT::CDROM::NoMount", "false") + + def add(self, progress: CdromProgress | None = None) -> bool: + """Add cdrom to the sources.list.""" + return apt_pkg.Cdrom.add(self, progress or self._progress) + + def ident(self, progress: CdromProgress | None = None) -> str: + """Identify the cdrom.""" + return apt_pkg.Cdrom.ident(self, progress or self._progress) + + @property + def in_sources_list(self) -> bool: + """Check if the cdrom is already in the current sources.list.""" + cd_id = self.ident() + if cd_id is None: + # FIXME: throw exception instead + return False + # Get a list of files + src = glob.glob(apt_pkg.config.find_dir("Dir::Etc::sourceparts") + "*") + src.append(apt_pkg.config.find_file("Dir::Etc::sourcelist")) + # Check each file + for fname in src: + with open(fname) as fobj: + for line in fobj: + if not line.lstrip().startswith("#") and cd_id in line: + return True + return False diff --git a/apt/debfile.py b/apt/debfile.py new file mode 100644 index 0000000..b3ef733 --- /dev/null +++ b/apt/debfile.py @@ -0,0 +1,861 @@ +# Copyright (c) 2005-2010 Canonical +# +# Author: Michael Vogt +# +# 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 +"""Classes for working with locally available Debian packages.""" + +import gzip +import os +import sys +from collections.abc import Iterable +from io import BytesIO +from typing import cast + +import apt_inst +import apt_pkg +from apt_pkg import gettext as _ + +import apt + + +class NoDebArchiveException(IOError): + """Exception which is raised if a file is no Debian archive.""" + + +class DebPackage: + """A Debian Package (.deb file).""" + + # Constants for comparing the local package file with the version + # in the cache + (VERSION_NONE, VERSION_OUTDATED, VERSION_SAME, VERSION_NEWER) = range(4) + + debug = 0 + + def __init__( + self, filename: str | None = None, cache: apt.Cache | None = None + ) -> None: + if cache is None: + cache = apt.Cache() + self._cache = cache + self._debfile = cast(apt_inst.DebFile, None) + self.pkgname = "" + self.filename: str | None = None + self._sections: dict[str, str] | apt_pkg.TagSection[str] = {} # noqa + self._need_pkgs: list[str] = [] + self._check_was_run = False + self._failure_string = "" + self._multiarch: str | None = None + if filename: + self.open(filename) + + def open(self, filename: str) -> None: + """open given debfile""" + self._dbg(3, "open '%s'" % filename) + self._need_pkgs = [] + self._installed_conflicts: set[str] = set() + self._failure_string = "" + self.filename = filename + self._debfile = apt_inst.DebFile(self.filename) + control = self._debfile.control.extractdata("control") + self._sections = apt_pkg.TagSection(control) + self.pkgname = self._sections["Package"] + self._check_was_run = False + + def __getitem__(self, key: str) -> str: + return self._sections[key] + + def __contains__(self, key: str) -> bool: + return key in self._sections + + @property + def filelist(self) -> list[str]: + """return the list of files in the deb.""" + files = [] + try: + self._debfile.data.go(lambda item, data: files.append(item.name)) + except SystemError: + return [_("List of files for '%s' could not be read") % self.filename] + return files + + @property + def control_filelist(self) -> list[str]: + """return the list of files in control.tar.gz""" + control = [] + try: + self._debfile.control.go(lambda item, data: control.append(item.name)) + except SystemError: + return [ + _("List of control files for '%s' could not be read") % self.filename + ] + return sorted(control) + + # helper that will return a pkgname with a multiarch suffix if needed + def _maybe_append_multiarch_suffix( + self, pkgname: str, in_conflict_checking: bool = False + ) -> str: + # trivial cases + if ":" in pkgname: + return pkgname + if not self._multiarch: + return pkgname + elif self._cache.is_virtual_package(pkgname): + return pkgname + elif ( + pkgname in self._cache + and self._cache[pkgname].candidate is not None + and cast(apt.package.Version, self._cache[pkgname].candidate).architecture + == "all" + ): + return pkgname + # now do the real multiarch checking + multiarch_pkgname = f"{pkgname}:{self._multiarch}" + # the upper layers will handle this + if multiarch_pkgname not in self._cache: + return multiarch_pkgname + multiarch_pkg = self._cache[multiarch_pkgname] + if multiarch_pkg.candidate is None: + return multiarch_pkgname + # now check the multiarch state + cand = multiarch_pkg.candidate._cand + # print pkgname, multiarch_pkgname, cand.multi_arch + # the default is to add the suffix, unless its a pkg that can satify + # foreign dependencies + if cand.multi_arch & cand.MULTI_ARCH_FOREIGN: + return pkgname + # for conflicts we need a special case here, any not multiarch enabled + # package has a implicit conflict + if in_conflict_checking and not (cand.multi_arch & cand.MULTI_ARCH_SAME): + return pkgname + return multiarch_pkgname + + def _is_or_group_satisfied(self, or_group: list[tuple[str, str, str]]) -> bool: + """Return True if at least one dependency of the or-group is satisfied. + + This method gets an '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] + + # multiarch + depname = self._maybe_append_multiarch_suffix(depname) + + # check for virtual pkgs + if depname not in self._cache: + if self._cache.is_virtual_package(depname): + self._dbg( + 3, "_is_or_group_satisfied(): %s is virtual dep" % depname + ) + for pkg in self._cache.get_providing_packages(depname): + if pkg.is_installed: + return True + continue + # check real dependency + inst = self._cache[depname].installed + if inst is not None and apt_pkg.check_dep(inst.version, oper, ver): + return True + + # if no real dependency is installed, check if there is + # a package installed that provides this dependency + # (e.g. scrollkeeper dependecies are provided by rarian-compat) + # but only do that if there is no version required in the + # dependency (we do not supprot versionized dependencies) + if not oper: + for ppkg in self._cache.get_providing_packages( + depname, include_nonvirtual=True + ): + if ppkg.is_installed: + self._dbg( + 3, + "found installed '%s' that provides '%s'" + % (ppkg.name, depname), + ) + return True + return False + + def _satisfy_or_group(self, or_group: list[tuple[str, str, str]]) -> bool: + """Try to satisfy the or_group.""" + for dep in or_group: + depname, ver, oper = dep + + # multiarch + depname = self._maybe_append_multiarch_suffix(depname) + + # if we don't have it in the cache, it may be virtual + if depname not in self._cache: + if not self._cache.is_virtual_package(depname): + continue + providers = self._cache.get_providing_packages(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 + pkg = self._cache[depname] + cand = self._cache._depcache.get_candidate_ver(pkg._pkg) + if not cand: + continue + if not apt_pkg.check_dep(cand.ver_str, oper, ver): + continue + + # check if we need to install it + self._dbg(2, "Need to get: %s" % depname) + self._need_pkgs.append(depname) + return True + + # if we reach this point, we failed + or_str = "" + for dep in or_group: + or_str += dep[0] + if ver and oper: + or_str += f" ({dep[2]} {dep[1]})" + if dep != or_group[len(or_group) - 1]: + or_str += "|" + self._failure_string += _("Dependency is not satisfiable: %s\n") % or_str + return False + + def _check_single_pkg_conflict(self, pkgname: str, ver: str, oper: str) -> bool: + """Return 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, + "_check_single_pkg_conflict() pkg='%s' ver='%s' oper='%s'" + % (pkgname, ver, oper), + ) + pkg = self._cache[pkgname] + if pkg.is_installed: + assert pkg.installed is not None + pkgver = pkg.installed.version + elif pkg.marked_install: + assert pkg.candidate is not None + pkgver = pkg.candidate.version + else: + return False + # print "pkg: %s" % pkgname + # print "ver: %s" % ver + # print "pkgver: %s " % pkgver + # print "oper: %s " % oper + if apt_pkg.check_dep(pkgver, oper, ver) and not self.replaces_real_pkg( + pkgname, oper, ver + ): + self._failure_string += ( + _("Conflicts with the installed package " "'%s'") % pkg.name + ) + self._dbg(3, "conflicts with installed pkg '%s'" % pkg.name) + return True + return False + + def _check_conflicts_or_group(self, or_group: list[tuple[str, str, str]]) -> bool: + """Check the or-group for conflicts with installed pkgs.""" + self._dbg(2, "_check_conflicts_or_group(): %s " % (or_group)) + for dep in or_group: + depname = dep[0] + ver = dep[1] + oper = dep[2] + + # FIXME: is this good enough? i.e. will apt always populate + # the cache with conflicting pkgnames for our arch? + depname = self._maybe_append_multiarch_suffix( + depname, in_conflict_checking=True + ) + + # check conflicts with virtual pkgs + if depname not in self._cache: + # FIXME: we have to check for virtual replaces here as + # well (to pass tests/gdebi-test8.deb) + if self._cache.is_virtual_package(depname): + for pkg in self._cache.get_providing_packages(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._check_single_pkg_conflict(pkg.name, ver, oper): + self._installed_conflicts.add(pkg.name) + continue + if self._check_single_pkg_conflict(depname, ver, oper): + self._installed_conflicts.add(depname) + return bool(self._installed_conflicts) + + @property + def conflicts(self) -> list[list[tuple[str, str, str]]]: + """List of packages conflicting with this package.""" + key = "Conflicts" + try: + return apt_pkg.parse_depends(self._sections[key], False) + except KeyError: + return [] + + @property + def depends(self) -> list[list[tuple[str, str, str]]]: + """List of packages on which this package depends on.""" + depends = [] + # find depends + for key in "Depends", "Pre-Depends": + try: + depends.extend(apt_pkg.parse_depends(self._sections[key], False)) + except KeyError: + pass + return depends + + @property + def provides(self) -> list[list[tuple[str, str, str]]]: + """List of virtual packages which are provided by this package.""" + key = "Provides" + try: + return apt_pkg.parse_depends(self._sections[key], False) + except KeyError: + return [] + + @property + def replaces(self) -> list[list[tuple[str, str, str]]]: + """List of packages which are replaced by this package.""" + key = "Replaces" + try: + return apt_pkg.parse_depends(self._sections[key], False) + except KeyError: + return [] + + def replaces_real_pkg(self, pkgname: str, oper: str, ver: str) -> bool: + """Return True if a given non-virtual package is replaced. + + Return True if the deb packages replaces a real (not virtual) + packages named (pkgname, oper, ver). + """ + self._dbg(3, f"replaces_real_pkg() {pkgname} {oper} {ver}") + pkg = self._cache[pkgname] + pkgver: str | None = None + if pkg.is_installed: + assert pkg.installed is not None + pkgver = pkg.installed.version + elif pkg.marked_install: + assert pkg.candidate is not None + pkgver = pkg.candidate.version + else: + pkgver = None + for or_group in self.replaces: + for name, ver, oper in or_group: + if name == pkgname and ( + pkgver is None or apt_pkg.check_dep(pkgver, oper, ver) + ): + self._dbg( + 3, + "we have a replaces in our package for the " + "conflict against '%s'" % (pkgname), + ) + return True + return False + + def check_conflicts(self) -> bool: + """Check if there are conflicts with existing or selected packages. + + Check if the package conflicts with a existing or to be installed + package. Return True if the pkg is OK. + """ + res = True + for or_group in self.conflicts: + if self._check_conflicts_or_group(or_group): + # print "Conflicts with a exisiting pkg!" + # self._failure_string = "Conflicts with a exisiting pkg!" + res = False + return res + + def check_breaks_existing_packages(self) -> bool: + """ + check if installing the package would break exsisting + package on the system, e.g. system has: + smc depends on smc-data (= 1.4) + and user tries to installs smc-data 1.6 + """ + # show progress information as this step may take some time + size = float(len(self._cache)) + steps = max(int(size / 50), 1) + debver = self._sections["Version"] + debarch = self._sections["Architecture"] + # store what we provide so that we can later check against that + provides = [x[0][0] for x in self.provides] + for i, pkg in enumerate(self._cache): + if i % steps == 0: + self._cache.op_progress.update(float(i) / size * 100.0) + if not pkg.is_installed: + continue + assert pkg.installed is not None + # check if the exising dependencies are still satisfied + # with the package + ver = pkg._pkg.current_ver + for dep_or in pkg.installed.dependencies: + for dep in dep_or.or_dependencies: + if dep.name == self.pkgname: + if not apt_pkg.check_dep(debver, dep.relation, dep.version): + self._dbg(2, "would break (depends) %s" % pkg.name) + # TRANSLATORS: the first '%s' is the package that + # breaks, the second the dependency that makes it + # break, the third the relation (e.g. >=) and the + # latest the version for the releation + self._failure_string += _( + "Breaks existing package '%(pkgname)s' " + "dependency %(depname)s " + "(%(deprelation)s %(depversion)s)" + ) % { + "pkgname": pkg.name, + "depname": dep.name, + "deprelation": dep.relation, + "depversion": dep.version, + } + self._cache.op_progress.done() + return False + # now check if there are conflicts against this package on + # the existing system + if "Conflicts" in ver.depends_list: + for conflicts_ver_list in ver.depends_list["Conflicts"]: + for c_or in conflicts_ver_list: + if ( + c_or.target_pkg.name == self.pkgname + and c_or.target_pkg.architecture == debarch + ): + if apt_pkg.check_dep( + debver, c_or.comp_type, c_or.target_ver + ): + self._dbg(2, "would break (conflicts) %s" % pkg.name) + # TRANSLATORS: the first '%s' is the package + # that conflicts, the second the packagename + # that it conflicts with (so the name of the + # deb the user tries to install), the third is + # the relation (e.g. >=) and the last is the + # version for the relation + self._failure_string += _( + "Breaks existing package '%(pkgname)s' " + "conflict: %(targetpkg)s " + "(%(comptype)s %(targetver)s)" + ) % { + "pkgname": pkg.name, + "targetpkg": c_or.target_pkg.name, + "comptype": c_or.comp_type, + "targetver": c_or.target_ver, + } + self._cache.op_progress.done() + return False + if ( + c_or.target_pkg.name in provides + and self.pkgname != pkg.name + ): + self._dbg(2, "would break (conflicts) %s" % provides) + self._failure_string += _( + "Breaks existing package '%(pkgname)s' " + "that conflict: '%(targetpkg)s'. But the " + "'%(debfile)s' provides it via: " + "'%(provides)s'" + ) % { + "provides": ",".join(provides), + "debfile": self.filename, + "targetpkg": c_or.target_pkg.name, + "pkgname": pkg.name, + } + self._cache.op_progress.done() + return False + self._cache.op_progress.done() + return True + + def compare_to_version_in_cache(self, use_installed: bool = True) -> int: + """Compare the package to the version available in the cache. + + Checks if the package is already installed or availabe in the cache + and if so in what version, returns one of (VERSION_NONE, + VERSION_OUTDATED, VERSION_SAME, VERSION_NEWER). + """ + self._dbg(3, "compare_to_version_in_cache") + pkgname = self._sections["Package"] + architecture = self._sections["Architecture"] + + # Arch qualify the package name + pkgname = ":".join([pkgname, architecture]) + + debver = self._sections["Version"] + self._dbg(1, "debver: %s" % debver) + if pkgname in self._cache: + pkg = self._cache[pkgname] + if use_installed and pkg.installed is not None: + cachever = pkg.installed.version + elif not use_installed and pkg.candidate is not None: + cachever = pkg.candidate.version + else: + return self.VERSION_NONE + if cachever is not None: + cmp = apt_pkg.version_compare(cachever, debver) + self._dbg(1, "CompareVersion(debver,instver): %s" % cmp) + if cmp == 0: + return self.VERSION_SAME + elif cmp < 0: + return self.VERSION_NEWER + elif cmp > 0: + return self.VERSION_OUTDATED + return self.VERSION_NONE + + def check(self, allow_downgrade: bool = False) -> bool: + """Check if the package is installable.""" + self._dbg(3, "check") + + self._check_was_run = True + + # check arch + if "Architecture" not in self._sections: + self._dbg(1, "ERROR: no architecture field") + self._failure_string = _("No Architecture field in the package") + return False + arch = self._sections["Architecture"] + if arch != "all" and arch != apt_pkg.config.find("APT::Architecture"): + if arch in apt_pkg.get_architectures(): + self._multiarch = arch + self.pkgname = f"{self.pkgname}:{self._multiarch}" + self._dbg(1, "Found multiarch arch: '%s'" % arch) + else: + self._dbg(1, "ERROR: Wrong architecture dude!") + self._failure_string = ( + _( + "Wrong architecture '%s' " + "-- Run dpkg --add-architecture to " + "add it and update afterwards" + ) + % arch + ) + return False + + # check version + if ( + not allow_downgrade + and self.compare_to_version_in_cache() == self.VERSION_OUTDATED + ): + if self._cache[self.pkgname].installed: + # the deb is older than the installed + self._failure_string = _("A later version is already installed") + return False + + # FIXME: this sort of error handling sux + self._failure_string = "" + + # check conflicts + if not self.check_conflicts(): + return False + + # check if installing it would break anything on the + # current system + if not self.check_breaks_existing_packages(): + return False + + # try to satisfy the dependencies + if not self._satisfy_depends(self.depends): + return False + + # check for conflicts again (this time with the packages that are + # makeed for install) + if not self.check_conflicts(): + return False + + if self._cache._depcache.broken_count > 0: + self._failure_string = _( + "Failed to satisfy all dependencies " "(broken cache)" + ) + # clean the cache again + self._cache.clear() + return False + return True + + def satisfy_depends_str(self, dependsstr: str) -> bool: + """Satisfy the dependencies in the given string.""" + return self._satisfy_depends(apt_pkg.parse_depends(dependsstr, False)) + + def _satisfy_depends(self, depends: list[list[tuple[str, str, str]]]) -> bool: + """Satisfy the dependencies.""" + # turn off MarkAndSweep via a action group (if available) + try: + _actiongroup = apt_pkg.ActionGroup(self._cache._depcache) + _actiongroup # pyflakes + except AttributeError: + pass + # check depends + for or_group in depends: + if not self._is_or_group_satisfied(or_group): + if not self._satisfy_or_group(or_group): + return False + # now try it out in the cache + for pkg in self._need_pkgs: + try: + self._cache[pkg].mark_install(from_user=False) + except SystemError: + self._failure_string = _("Cannot install '%s'") % pkg + self._cache.clear() + return False + return True + + @property + def missing_deps(self) -> list[str]: + """Return missing dependencies.""" + self._dbg(1, "Installing: %s" % self._need_pkgs) + if not self._check_was_run: + raise AttributeError("property only available after check() was run") + return self._need_pkgs + + @property + def required_changes(self) -> tuple[list[str], list[str], list[str]]: + """Get the changes required to satisfy the dependencies. + + Returns: a tuple with (install, remove, unauthenticated) + """ + install = [] + remove = [] + unauthenticated = [] + if not self._check_was_run: + raise AttributeError("property only available after check() was run") + for pkg in self._cache: + if pkg.marked_install or pkg.marked_upgrade: + assert pkg.candidate is not None + install.append(pkg.name) + # check authentication, one authenticated origin is enough + # libapt will skip non-authenticated origins then + authenticated = False + for origin in pkg.candidate.origins: + authenticated |= origin.trusted + if not authenticated: + unauthenticated.append(pkg.name) + if pkg.marked_delete: + remove.append(pkg.name) + return (install, remove, unauthenticated) + + @staticmethod + def to_hex(in_data: str) -> str: + hex = "" + for i, c in enumerate(in_data): + if i % 80 == 0: + hex += "\n" + hex += "%2.2x " % ord(c) + return hex + + @staticmethod + def to_strish(in_data: str | Iterable[int]) -> str: + s = "" + # py2 compat, in_data is type string + if isinstance(in_data, str): + for c in in_data: + if ord(c) < 10 or ord(c) > 127: + s += " " + else: + s += c + # py3 compat, in_data is type bytes + else: + for b in in_data: + if b < 10 or b > 127: + s += " " + else: + s += chr(b) + return s + + def _get_content( + self, + part: apt_inst.TarFile, + name: str, + auto_decompress: bool = True, + auto_hex: bool = True, + ) -> str: + if name.startswith("./"): + name = name[2:] + data = part.extractdata(name) + # check for zip content + if name.endswith(".gz") and auto_decompress: + io = BytesIO(data) + gz = gzip.GzipFile(fileobj=io) + data = _("Automatically decompressed:\n\n").encode("utf-8") + data += gz.read() + # auto-convert to hex + try: + return data.decode("utf-8") + except Exception: + new_data = _("Automatically converted to printable ascii:\n") + new_data += self.to_strish(data) + return new_data + + def control_content(self, name: str) -> str: + """return the content of a specific control.tar.gz file""" + try: + return self._get_content(self._debfile.control, name) + except LookupError: + return "" + + def data_content(self, name: str) -> str: + """return the content of a specific control.tar.gz file""" + try: + return self._get_content(self._debfile.data, name) + except LookupError: + return "" + + def _dbg(self, level: int, msg: str) -> None: + """Write debugging output to sys.stderr.""" + if level <= self.debug: + print(msg, file=sys.stderr) + + def install( + self, install_progress: apt.progress.base.InstallProgress | None = None + ) -> int: + """Install the package.""" + if self.filename is None: + raise apt_pkg.Error("No filename specified") + if install_progress is None: + return os.spawnlp(os.P_WAIT, "dpkg", "dpkg", "-i", self.filename) + else: + try: + install_progress.start_update() + except AttributeError: + install_progress.startUpdate() # type: ignore + res = install_progress.run(self.filename) + try: + install_progress.finish_update() + except AttributeError: + install_progress.finishUpdate() # type: ignore + return res + + +class DscSrcPackage(DebPackage): + """A locally available source package.""" + + def __init__( + self, filename: str | None = None, cache: apt.Cache | None = None + ) -> None: + DebPackage.__init__(self, None, cache) + self.filename: str | None = filename + self._depends: list[list[tuple[str, str, str]]] = [] + self._conflicts: list[list[tuple[str, str, str]]] = [] + self._installed_conflicts: set[str] = set() + self.pkgname = "" + self.binaries: list[str] = [] + self._sections: dict[str, str] = {} + if self.filename is not None: + self.open(self.filename) + + @property + def depends(self) -> list[list[tuple[str, str, str]]]: + """Return the dependencies of the package""" + return self._depends + + @property + def conflicts(self) -> list[list[tuple[str, str, str]]]: + """Return the dependencies of the package""" + return self._conflicts + + @property + def filelist(self) -> list[str]: + """Return the list of files associated with this dsc file""" + # Files stanza looks like (hash, size, filename, ...) + return self._sections["Files"].split()[2::3] + + def open(self, file: str) -> None: + """Open the package.""" + depends_tags = ["Build-Depends", "Build-Depends-Indep"] + conflicts_tags = ["Build-Conflicts", "Build-Conflicts-Indep"] + fd = apt_pkg.open_maybe_clear_signed_file(file) + fobj = os.fdopen(fd) + tagfile = apt_pkg.TagFile(fobj) + try: + for sec in tagfile: + for tag in depends_tags: + if tag not in sec: + continue + self._depends.extend(apt_pkg.parse_src_depends(sec[tag])) + for tag in conflicts_tags: + if tag not in sec: + continue + self._conflicts.extend(apt_pkg.parse_src_depends(sec[tag])) + if "Source" in sec: + self.pkgname = sec["Source"] + if "Binary" in sec: + self.binaries = [b.strip() for b in sec["Binary"].split(",")] + for tag in sec.keys(): + if tag in sec: + self._sections[tag] = sec[tag] + finally: + del tagfile + fobj.close() + + s = _( + "Install Build-Dependencies for " "source package '%s' that builds %s\n" + ) % (self.pkgname, " ".join(self.binaries)) + self._sections["Description"] = s + self._check_was_run = False + + def check(self, allow_downgrade: bool = False) -> bool: + """Check if the package is installable. + + The second parameter is ignored and only exists for compatibility + with parent type.""" + if not self.check_conflicts(): + for pkgname in self._installed_conflicts: + if self._cache[pkgname]._pkg.essential: + raise Exception(_("An essential package would be removed")) + self._cache[pkgname].mark_delete() + # properties are ok now + self._check_was_run = True + # FIXME: a additional run of the check_conflicts() + # after _satisfy_depends() should probably be done + return self._satisfy_depends(self.depends) + + +def _test() -> None: + """Test function""" + from apt.cache import Cache + from apt.progress.base import InstallProgress + + cache = Cache() + + vp = "www-browser" + print(f"{vp} virtual: {cache.is_virtual_package(vp)}") + providers = cache.get_providing_packages(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.check(): + print("can't be satified") + print(d._failure_string) + print("missing deps: %s" % d.missing_deps) + print(d.required_changes) + + print(d.filelist) + + print("Installing ...") + ret = d.install(InstallProgress()) + print(ret) + + # s = DscSrcPackage(cache, "../tests/3ddesktop_0.2.9-6.dsc") + # s.check_dep() + # print "Missing deps: ",s.missingDeps + # print "Print required changes: ", s.requiredChanges + + s = DscSrcPackage(cache=cache) + ds = "libc6 (>= 2.3.2), libaio (>= 0.3.96) | libaio1 (>= 0.3.96)" + print(s._satisfy_depends(apt_pkg.parse_depends(ds, False))) + + +if __name__ == "__main__": + _test() diff --git a/apt/package.py b/apt/package.py new file mode 100644 index 0000000..50ed6d1 --- /dev/null +++ b/apt/package.py @@ -0,0 +1,1559 @@ +# package.py - apt package abstraction +# +# Copyright (c) 2005-2009 Canonical +# +# Author: Michael Vogt +# +# 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 +"""Functionality related to packages.""" +from __future__ import annotations + +import logging +import os +import re +import socket +import subprocess +import sys +import threading +from collections.abc import Iterable, Iterator, Mapping, Sequence +from http.client import BadStatusLine +from typing import Any, no_type_check +from urllib.error import HTTPError +from urllib.request import urlopen + +import apt_pkg +from apt_pkg import gettext as _ + +import apt.progress.text +from apt.progress.base import AcquireProgress, InstallProgress + +__all__ = ( + "BaseDependency", + "Dependency", + "Origin", + "Package", + "Record", + "Version", + "VersionList", +) + + +def _file_is_same(path: str, size: int, hashes: apt_pkg.HashStringList) -> bool: + """Return ``True`` if the file is the same.""" + if os.path.exists(path) and os.path.getsize(path) == size: + with open(path) as fobj: + return apt_pkg.Hashes(fobj).hashes == hashes + return False + + +class FetchError(Exception): + """Raised when a file could not be fetched.""" + + +class UntrustedError(FetchError): + """Raised when a file did not have a trusted hash.""" + + +class BaseDependency: + """A single dependency.""" + + class __dstr(str): + """Compare helper for compatibility with old third-party code. + + Old third-party code might still compare the relation with the + previously used relations (<<,<=,==,!=,>=,>>,) instead of the curently + used ones (<,<=,=,!=,>=,>,). This compare helper lets < match to <<, + > match to >> and = match to ==. + """ + + def __eq__(self, other: object) -> bool: + if str.__eq__(self, other): + return True + elif str.__eq__(self, "<"): + return str.__eq__("<<", other) + elif str.__eq__(self, ">"): + return str.__eq__(">>", other) + elif str.__eq__(self, "="): + return str.__eq__("==", other) + else: + return False + + def __ne__(self, other: object) -> bool: + return not self.__eq__(other) + + def __init__(self, version: Version, dep: apt_pkg.Dependency) -> None: + self._version = version # apt.package.Version + self._dep = dep # apt_pkg.Dependency + + def __str__(self) -> str: + return f"{self.rawtype}: {self.rawstr}" + + def __repr__(self) -> str: + return "".format( + self.name, + self.relation, + self.version, + self.rawtype, + ) + + @property + def name(self) -> str: + """The name of the target package.""" + return self._dep.target_pkg.name + + @property + def relation(self) -> str: + """The relation (<, <=, =, !=, >=, >, '') in mathematical notation. + + The empty string will be returned in case of an unversioned dependency. + """ + return self.__dstr(self._dep.comp_type) + + @property + def relation_deb(self) -> str: + """The relation (<<, <=, =, !=, >=, >>, '') in Debian notation. + + The empty string will be returned in case of an unversioned dependency. + For more details see the Debian Policy Manual on the syntax of + relationship fields: + https://www.debian.org/doc/debian-policy/ch-relationships.html#s-depsyntax # noqa + + .. versionadded:: 1.0.0 + """ + return self._dep.comp_type_deb + + @property + def version(self) -> str: + """The target version or an empty string. + + Note that the version is only an empty string in case of an unversioned + dependency. In this case the relation is also an empty string. + """ + return self._dep.target_ver + + @property + def target_versions(self) -> list[Version]: + """A list of all Version objects which satisfy this dependency. + + .. versionadded:: 1.0.0 + """ + tvers = [] + _tvers: list[apt_pkg.Version] = self._dep.all_targets() + for _tver in _tvers: # type: apt_pkg.Version + _pkg: apt_pkg.Package = _tver.parent_pkg + cache = self._version.package._pcache # apt.cache.Cache + pkg = cache._rawpkg_to_pkg(_pkg) # apt.package.Package + tver = Version(pkg, _tver) # apt.package.Version + tvers.append(tver) + return tvers + + @property + def installed_target_versions(self) -> list[Version]: + """A list of all installed Version objects which satisfy this dep. + + .. versionadded:: 1.0.0 + """ + return [tver for tver in self.target_versions if tver.is_installed] + + @property + def rawstr(self) -> str: + """String represenation of the dependency. + + Returns the string representation of the dependency as it would be + written in the debian/control file. The string representation does not + include the type of the dependency. + + Example for an unversioned dependency: + python3 + + Example for a versioned dependency: + python3 >= 3.2 + + .. versionadded:: 1.0.0 + """ + if self.version: + return f"{self.name} {self.relation_deb} {self.version}" + else: + return self.name + + @property + def rawtype(self) -> str: + """Type of the dependency. + + This should be one of 'Breaks', 'Conflicts', 'Depends', 'Enhances', + 'PreDepends', 'Recommends', 'Replaces', 'Suggests'. + + Additional types might be added in the future. + """ + return self._dep.dep_type_untranslated + + @property + def pre_depend(self) -> bool: + """Whether this is a PreDepends.""" + return self._dep.dep_type_untranslated == "PreDepends" + + +class Dependency(list[BaseDependency]): + """Represent an Or-group of dependencies. + + Attributes defined here: + or_dependencies - The possible choices + rawstr - String represenation of the Or-group of dependencies + rawtype - The type of the dependencies in the Or-group + target_version - A list of Versions which satisfy this Or-group of deps + """ + + def __init__( + self, version: Version, base_deps: list[BaseDependency], rawtype: str + ) -> None: + super().__init__(base_deps) + self._version = version # apt.package.Version + self._rawtype = rawtype + + def __str__(self) -> str: + return f"{self.rawtype}: {self.rawstr}" + + def __repr__(self) -> str: + return "" % (", ".join(repr(bd) for bd in self)) + + @property + def or_dependencies(self) -> Dependency: + return self + + @property + def rawstr(self) -> str: + """String represenation of the Or-group of dependencies. + + Returns the string representation of the Or-group of dependencies as it + would be written in the debian/control file. The string representation + does not include the type of the Or-group of dependencies. + + Example: + python2 >= 2.7 | python3 + + .. versionadded:: 1.0.0 + """ + return " | ".join(bd.rawstr for bd in self) + + @property + def rawtype(self) -> str: + """Type of the Or-group of dependency. + + This should be one of 'Breaks', 'Conflicts', 'Depends', 'Enhances', + 'PreDepends', 'Recommends', 'Replaces', 'Suggests'. + + Additional types might be added in the future. + + .. versionadded:: 1.0.0 + """ + return self._rawtype + + @property + def target_versions(self) -> list[Version]: + """A list of all Version objects which satisfy this Or-group of deps. + + .. versionadded:: 1.0.0 + """ + tvers: list[Version] = [] + for bd in self: # apt.package.Dependency + for tver in bd.target_versions: # apt.package.Version + if tver not in tvers: + tvers.append(tver) + return tvers + + @property + def installed_target_versions(self) -> list[Version]: + """A list of all installed Version objects which satisfy this dep. + + .. versionadded:: 1.0.0 + """ + return [tver for tver in self.target_versions if tver.is_installed] + + +class Origin: + """The origin of a version. + + Attributes defined here: + archive - The archive (eg. unstable) + component - The component (eg. main) + label - The Label, as set in the Release file + origin - The Origin, as set in the Release file + codename - The Codename, as set in the Release file + site - The hostname of the site. + trusted - Boolean value whether this is trustworthy. + """ + + def __init__(self, pkg: Package, packagefile: apt_pkg.PackageFile) -> None: + self.archive = packagefile.archive + self.component = packagefile.component + self.label = packagefile.label + self.origin = packagefile.origin + self.codename = packagefile.codename + self.site = packagefile.site + self.not_automatic = packagefile.not_automatic + # check the trust + indexfile = pkg._pcache._list.find_index(packagefile) + if indexfile and indexfile.is_trusted: + self.trusted = True + else: + self.trusted = False + + def __repr__(self) -> str: + return ( + "" + ) % ( + self.component, + self.archive, + self.origin, + self.label, + self.site, + self.trusted, + ) + + +class Record(Mapping[Any, Any]): + """Record in a Packages file + + Represent a record as stored in a Packages file. You can use this like + a dictionary mapping the field names of the record to their values:: + + >>> record = Record("Package: python-apt\\nVersion: 0.8.0\\n\\n") + >>> record["Package"] + 'python-apt' + >>> record["Version"] + '0.8.0' + + For example, to get the tasks of a package from a cache, you could do:: + + package.candidate.record["Tasks"].split() + + Of course, you can also use the :attr:`Version.tasks` property. + + """ + + def __init__(self, record_str: str) -> None: + self._rec = apt_pkg.TagSection(record_str) + + def __hash__(self) -> int: + return hash(self._rec) + + def __str__(self) -> str: + return str(self._rec) + + def __getitem__(self, key: str) -> str: + return self._rec[key] + + def __contains__(self, key: object) -> bool: + return key in self._rec + + def __iter__(self) -> Iterator[str]: + return iter(self._rec.keys()) + + def iteritems(self) -> Iterable[tuple[object, str]]: + """An iterator over the (key, value) items of the record.""" + for key in self._rec.keys(): + yield key, self._rec[key] + + def get(self, key: str, default: object = None) -> object: + """Return record[key] if key in record, else *default*. + + The parameter *default* must be either a string or None. + """ + return self._rec.get(key, default) + + def has_key(self, key: str) -> bool: + """deprecated form of ``key in x``.""" + return key in self._rec + + def __len__(self) -> int: + return len(self._rec) + + +class Version: + """Representation of a package version. + + The Version class contains all information related to a + specific package version. + + .. versionadded:: 0.7.9 + """ + + def __init__(self, package: Package, cand: apt_pkg.Version) -> None: + self.package = package + self._cand = cand + self.package._pcache._weakversions.add(self) + + def _cmp(self, other: Any) -> int | Any: + """Compares against another apt.Version object or a version string. + + This method behaves like Python 2's cmp builtin and returns an integer + according to the outcome. The return value is negative in case of + self < other, zero if self == other and positive if self > other. + + The comparison includes the package name and architecture if other is + an apt.Version object. If other isn't an apt.Version object it'll be + assumed that other is a version string (without package name/arch). + + .. versionchanged:: 1.0.0 + """ + # Assume that other is an apt.Version object. + try: + self_name = self.package.fullname + other_name = other.package.fullname + if self_name < other_name: + return -1 + elif self_name > other_name: + return 1 + return apt_pkg.version_compare(self._cand.ver_str, other.version) + except AttributeError: + # Assume that other is a string that only contains the version. + try: + return apt_pkg.version_compare(self._cand.ver_str, other) + except TypeError: + return NotImplemented + + def __eq__(self, other: object) -> bool: + return self._cmp(other) == 0 + + def __ge__(self, other: Version) -> bool: + return self._cmp(other) >= 0 + + def __gt__(self, other: Version) -> bool: + return self._cmp(other) > 0 + + def __le__(self, other: Version) -> bool: + return self._cmp(other) <= 0 + + def __lt__(self, other: Version) -> bool: + return self._cmp(other) < 0 + + def __ne__(self, other: object) -> bool | Any: + try: + return self._cmp(other) != 0 + except TypeError: + return NotImplemented + + def __hash__(self) -> int: + return self._cand.hash + + def __str__(self) -> str: + return f"{self.package.name}={self.version}" + + def __repr__(self) -> str: + return f"" + + @property + def _records(self) -> apt_pkg.PackageRecords: + """Internal helper that moves the Records to the right position.""" + # If changing lookup, change fetch_binary() as well + if not self.package._pcache._records.lookup(self._cand.file_list[0]): + raise LookupError("Could not lookup record") + + return self.package._pcache._records + + @property + def _translated_records(self) -> apt_pkg.PackageRecords | None: + """Internal helper to get the translated description.""" + desc_iter = self._cand.translated_description + if self.package._pcache._records.lookup(desc_iter.file_list.pop(0)): + return self.package._pcache._records + return None + + @property + def is_security_update(self) -> bool: + """Return whether this version is a security update.""" + return bool(self._cand.is_security_update) + + @property + def installed_size(self) -> int: + """Return the size of the package when installed.""" + return self._cand.installed_size + + @property + def homepage(self) -> str: + """Return the homepage for the package.""" + return self._records.homepage + + @property + def size(self) -> int: + """Return the size of the package.""" + return self._cand.size + + @property + def architecture(self) -> str: + """Return the architecture of the package version.""" + return self._cand.arch + + @property + def downloadable(self) -> bool: + """Return whether the version of the package is downloadable.""" + return bool(self._cand.downloadable) + + @property + def is_installed(self) -> bool: + """Return wether this version of the package is currently installed. + + .. versionadded:: 1.0.0 + """ + inst_ver = self.package.installed + return inst_ver is not None and inst_ver._cand.id == self._cand.id + + @property + def version(self) -> str: + """Return the version as a string.""" + return self._cand.ver_str + + @property + def summary(self) -> str | None: + """Return the short description (one line summary).""" + records = self._translated_records + return records.short_desc if records is not None else None + + @property + def raw_description(self) -> str: + """return the long description (raw).""" + return self._records.long_desc + + @property + def section(self) -> str: + """Return the section of the package.""" + return self._cand.section + + @property + def description(self) -> str: + """Return the formatted long description. + + Return the formatted 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. + """ + desc = "" + records = self._translated_records + dsc = records.long_desc if records is not None else None + + if not dsc: + return _("Missing description for '%s'." "Please report.") % ( + self.package.name + ) + + try: + if not isinstance(dsc, str): + # Only convert where needed (i.e. Python 2.X) + dsc = dsc.decode("utf-8") + except UnicodeDecodeError as err: + return _( + "Invalid unicode in description for '%s' (%s). " "Please report." + ) % (self.package.name, err) + + lines = iter(dsc.split("\n")) + # Skip the first line, since its a duplication of the summary + next(lines) + for raw_line in lines: + if raw_line.strip() == ".": + # The line is just line break + if not desc.endswith("\n"): + desc += "\n\n" + continue + if 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 + # Add current line to the description + desc += line + return desc + + @property + def source_name(self) -> str: + """Return the name of the source package.""" + try: + return self._records.source_pkg or self.package.shortname + except IndexError: + return self.package.shortname + + @property + def source_version(self) -> str: + """Return the version of the source package.""" + try: + return self._records.source_ver or self._cand.ver_str + except IndexError: + return self._cand.ver_str + + @property + def priority(self) -> str: + """Return the priority of the package, as string.""" + return self._cand.priority_str + + @property + def policy_priority(self) -> int: + """Return the internal policy priority as a number. + See apt_preferences(5) for more information about what it means. + """ + return self.package._pcache._depcache.policy.get_priority(self._cand) + + @property + def record(self) -> Record: + """Return a Record() object for this version. + + Return a Record() object for this version which provides access + to the raw attributes of the candidate version + """ + return Record(self._records.record) + + def get_dependencies(self, *types: str) -> list[Dependency]: + """Return a list of Dependency objects for the given types. + + Multiple types can be specified. Possible types are: + 'Breaks', 'Conflicts', 'Depends', 'Enhances', 'PreDepends', + 'Recommends', 'Replaces', 'Suggests' + + Additional types might be added in the future. + """ + depends_list = [] + depends = self._cand.depends_list + for type_ in types: + try: + for dep_ver_list in depends[type_]: + base_deps = [] + for dep_or in dep_ver_list: + base_deps.append(BaseDependency(self, dep_or)) + depends_list.append(Dependency(self, base_deps, type_)) + except KeyError: + pass + return depends_list + + @property + def provides(self) -> list[str]: + """Return a list of names that this version provides.""" + return [p[0] for p in self._cand.provides_list] + + @property + def enhances(self) -> list[Dependency]: + """Return the list of enhances for the package version.""" + return self.get_dependencies("Enhances") + + @property + def dependencies(self) -> list[Dependency]: + """Return the dependencies of the package version.""" + return self.get_dependencies("PreDepends", "Depends") + + @property + def recommends(self) -> list[Dependency]: + """Return the recommends of the package version.""" + return self.get_dependencies("Recommends") + + @property + def suggests(self) -> list[Dependency]: + """Return the suggests of the package version.""" + return self.get_dependencies("Suggests") + + @property + def origins(self) -> list[Origin]: + """Return a list of origins for the package version.""" + origins = [] + for packagefile, _unused in self._cand.file_list: + origins.append(Origin(self.package, packagefile)) + return origins + + @property + def filename(self) -> str: + """Return the path to the file inside the archive. + + .. versionadded:: 0.7.10 + """ + return self._records.filename + + @property + def md5(self) -> str: + """Return the md5sum of the binary. + + .. versionadded:: 0.7.10 + """ + return self._records.md5_hash + + @property + def sha1(self) -> str: + """Return the sha1sum of the binary. + + .. versionadded:: 0.7.10 + """ + return self._records.sha1_hash + + @property + def sha256(self) -> str: + """Return the sha256sum of the binary. + + .. versionadded:: 0.7.10 + """ + return self._records.sha256_hash + + @property + def tasks(self) -> set[str]: + """Get the tasks of the package. + + A set of the names of the tasks this package belongs to. + + .. versionadded:: 0.8.0 + """ + return set(self.record["Task"].split()) + + def _uris(self) -> Iterator[str]: + """Return an iterator over all available urls. + + .. versionadded:: 0.7.10 + """ + for packagefile, _unused in self._cand.file_list: + indexfile = self.package._pcache._list.find_index(packagefile) + if indexfile: + yield indexfile.archive_uri(self._records.filename) + + @property + def uris(self) -> list[str]: + """Return a list of all available uris for the binary. + + .. versionadded:: 0.7.10 + """ + return list(self._uris()) + + @property + def uri(self) -> str | None: + """Return a single URI for the binary. + + .. versionadded:: 0.7.10 + """ + try: + return next(iter(self._uris())) + except StopIteration: + return None + + def fetch_binary( + self, + destdir: str = "", + progress: AcquireProgress | None = None, + allow_unauthenticated: bool | None = None, + ) -> str: + """Fetch the binary version of the package. + + The parameter *destdir* specifies the directory where the package will + be fetched to. + + The parameter *progress* may refer to an apt_pkg.AcquireProgress() + object. If not specified or None, apt.progress.text.AcquireProgress() + is used. + + The keyword-only parameter *allow_unauthenticated* specifies whether + to allow unauthenticated downloads. If not specified, it defaults to + the configuration option `APT::Get::AllowUnauthenticated`. + + .. versionadded:: 0.7.10 + """ + if allow_unauthenticated is None: + allow_unauthenticated = apt_pkg.config.find_b( + "APT::Get::" "AllowUnauthenticated", False + ) + base = os.path.basename(self._records.filename) + destfile = os.path.join(destdir, base) + if _file_is_same(destfile, self.size, self._records.hashes): + logging.debug("Ignoring already existing file: %s" % destfile) + return os.path.abspath(destfile) + + # Verify that the index is actually trusted + pfile, offset = self._cand.file_list[0] + index = self.package._pcache._list.find_index(pfile) + + if not (allow_unauthenticated or (index and index.is_trusted)): + raise UntrustedError( + "Could not fetch %s %s source package: " + "Source %r is not trusted" + % ( + self.package.name, + self.version, + getattr(index, "describe", ""), + ) + ) + if not self.uri: + raise ValueError("No URI for this binary.") + hashes = self._records.hashes + if not (allow_unauthenticated or hashes.usable): + raise UntrustedError( + "The item %r could not be fetched: " "No trusted hash found." % destfile + ) + acq = apt_pkg.Acquire(progress or apt.progress.text.AcquireProgress()) + acqfile = apt_pkg.AcquireFile( + acq, self.uri, hashes, self.size, base, destfile=destfile + ) + acq.run() + + if acqfile.status != acqfile.STAT_DONE: + raise FetchError( + "The item %r could not be fetched: %s" + % (acqfile.destfile, acqfile.error_text) + ) + + return os.path.abspath(destfile) + + def fetch_source( + self, + destdir: str = "", + progress: AcquireProgress | None = None, + unpack: bool = True, + allow_unauthenticated: bool | None = None, + ) -> str: + """Get the source code of a package. + + The parameter *destdir* specifies the directory where the source will + be fetched to. + + The parameter *progress* may refer to an apt_pkg.AcquireProgress() + object. If not specified or None, apt.progress.text.AcquireProgress() + is used. + + The parameter *unpack* describes whether the source should be unpacked + (``True``) or not (``False``). By default, it is unpacked. + + If *unpack* is ``True``, the path to the extracted directory is + returned. Otherwise, the path to the .dsc file is returned. + + The keyword-only parameter *allow_unauthenticated* specifies whether + to allow unauthenticated downloads. If not specified, it defaults to + the configuration option `APT::Get::AllowUnauthenticated`. + """ + if allow_unauthenticated is None: + allow_unauthenticated = apt_pkg.config.find_b( + "APT::Get::" "AllowUnauthenticated", False + ) + + src = apt_pkg.SourceRecords() + acq = apt_pkg.Acquire(progress or apt.progress.text.AcquireProgress()) + + dsc = None + record = self._records + source_name = record.source_pkg or self.package.shortname + source_version = record.source_ver or self._cand.ver_str + source_lookup = src.lookup(source_name) + + while source_lookup and source_version != src.version: + source_lookup = src.lookup(source_name) + if not source_lookup: + raise ValueError("No source for %r" % self) + files = list() + + if not (allow_unauthenticated or src.index.is_trusted): + raise UntrustedError( + "Could not fetch %s %s source package: " + "Source %r is not trusted" + % (self.package.name, self.version, src.index.describe) + ) + for fil in src.files: + base = os.path.basename(fil.path) + destfile = os.path.join(destdir, base) + if fil.type == "dsc": + dsc = destfile + if _file_is_same(destfile, fil.size, fil.hashes): + logging.debug("Ignoring already existing file: %s" % destfile) + continue + + if not (allow_unauthenticated or fil.hashes.usable): + raise UntrustedError( + "The item %r could not be fetched: " + "No trusted hash found." % destfile + ) + files.append( + apt_pkg.AcquireFile( + acq, + src.index.archive_uri(fil.path), + fil.hashes, + fil.size, + base, + destfile=destfile, + ) + ) + acq.run() + + if dsc is None: + raise ValueError("No source for %r" % self) + + for item in acq.items: + if item.status != item.STAT_DONE: + raise FetchError( + "The item %r could not be fetched: %s" + % (item.destfile, item.error_text) + ) + + if unpack: + outdir = src.package + "-" + apt_pkg.upstream_version(src.version) + outdir = os.path.join(destdir, outdir) + subprocess.check_call(["dpkg-source", "-x", dsc, outdir]) + return os.path.abspath(outdir) + else: + return os.path.abspath(dsc) + + +class VersionList(Sequence[Version]): + """Provide a mapping & sequence interface to all versions of a package. + + This class can be used like a dictionary, where version strings are the + keys. It can also be used as a sequence, where integers are the keys. + + You can also convert this to a dictionary or a list, using the usual way + of dict(version_list) or list(version_list). This is useful if you need + to access the version objects multiple times, because they do not have to + be recreated this way. + + Examples ('package.versions' being a version list): + '0.7.92' in package.versions # Check whether 0.7.92 is a valid version. + package.versions[0] # Return first version or raise IndexError + package.versions[0:2] # Return a new VersionList for objects 0-2 + package.versions['0.7.92'] # Return version 0.7.92 or raise KeyError + package.versions.keys() # All keys, as strings. + max(package.versions) + """ + + def __init__(self, package: Package, slice_: slice | None = None) -> None: + self._package = package # apt.package.Package() + self._versions = package._pkg.version_list # [apt_pkg.Version(), ...] + if slice_: + self._versions = self._versions[slice_] + + def __getitem__(self, item: int | slice | str) -> Any: + # FIXME: Should not be returning Any, should have overloads; but + # pyflakes complains + if isinstance(item, slice): + return self.__class__(self._package, item) + try: + # Sequence interface, item is an integer + return Version(self._package, self._versions[item]) # type: ignore + except TypeError: + # Dictionary interface item is a string. + for ver in self._versions: + if ver.ver_str == item: + return Version(self._package, ver) + raise KeyError("Version: %r not found." % (item)) + + def __str__(self) -> str: + return "[%s]" % (", ".join(str(ver) for ver in self)) + + def __repr__(self) -> str: + return "" % self.keys() + + def __iter__(self) -> Iterator[Version]: + """Return an iterator over all value objects.""" + return (Version(self._package, ver) for ver in self._versions) + + def __contains__(self, item: object) -> bool: + if isinstance(item, Version): # Sequence interface + item = item.version + # Dictionary interface. + for ver in self._versions: + if ver.ver_str == item: + return True + return False + + def __eq__(self, other: Any) -> bool: + return list(self) == list(other) + + def __len__(self) -> int: + return len(self._versions) + + # Mapping interface + + def keys(self) -> list[str]: + """Return a list of all versions, as strings.""" + return [ver.ver_str for ver in self._versions] + + def get(self, key: str, default: Version | None = None) -> Version | None: + """Return the key or the default.""" + try: + return self[key] # type: ignore # FIXME: should be deterined automatically # noqa + except LookupError: + return default + + +class Package: + """Representation of a package in a cache. + + This class provides methods and properties for working with a package. It + lets you mark the package for installation, check if it is installed, and + much more. + """ + + def __init__(self, pcache: apt.Cache, pkgiter: apt_pkg.Package) -> None: + """Init the Package object""" + self._pkg = pkgiter + self._pcache = pcache # python cache in cache.py + self._changelog = "" # Cached changelog + + def __str__(self) -> str: + return self.name + + def __repr__(self) -> str: + return "".format( + self._pkg.name, + self._pkg.architecture, + self._pkg.id, + ) + + def __lt__(self, other: Package) -> bool: + return self.name < other.name + + @property + def candidate(self) -> Version | None: + """Return the candidate version of the package. + + This property is writeable to allow you to set the candidate version + of the package. Just assign a Version() object, and it will be set as + the candidate version. + """ + cand = self._pcache._depcache.get_candidate_ver(self._pkg) + if cand is not None: + return Version(self, cand) + return None + + @candidate.setter + def candidate(self, version: Version) -> None: + """Set the candidate version of the package.""" + self._pcache.cache_pre_change() + self._pcache._depcache.set_candidate_ver(self._pkg, version._cand) + self._pcache.cache_post_change() + + @property + def installed(self) -> Version | None: + """Return the currently installed version of the package. + + .. versionadded:: 0.7.9 + """ + if self._pkg.current_ver is not None: + return Version(self, self._pkg.current_ver) + return None + + @property + def name(self) -> str: + """Return the name of the package, possibly including architecture. + + If the package is not part of the system's preferred architecture, + return the same as :attr:`fullname`, otherwise return the same + as :attr:`shortname` + + .. versionchanged:: 0.7.100.3 + + As part of multi-arch, this field now may include architecture + information. + """ + return self._pkg.get_fullname(True) + + @property + def fullname(self) -> str: + """Return the name of the package, including architecture. + + Note that as for :meth:`architecture`, this returns the + native architecture for Architecture: all packages. + + .. versionadded:: 0.7.100.3""" + return self._pkg.get_fullname(False) + + @property + def shortname(self) -> str: + """Return the name of the package, without architecture. + + .. versionadded:: 0.7.100.3""" + return self._pkg.name + + @property + def id(self) -> int: + """Return a uniq ID for the package. + + This can be used eg. to store additional information about the pkg.""" + return self._pkg.id + + @property + def essential(self) -> bool: + """Return True if the package is an essential part of the system.""" + return self._pkg.essential + + def architecture(self) -> str: + """Return the Architecture of the package. + + Note that for Architecture: all packages, this returns the + native architecture, as they are internally treated like native + packages. To get the concrete architecture, look at the + :attr:`Version.architecture` attribute. + + .. versionchanged:: 0.7.100.3 + This is now the package's architecture in the multi-arch sense, + previously it was the architecture of the candidate version + and deprecated. + """ + return self._pkg.architecture + + # depcache states + + @property + def marked_install(self) -> bool: + """Return ``True`` if the package is marked for install.""" + return self._pcache._depcache.marked_install(self._pkg) + + @property + def marked_upgrade(self) -> bool: + """Return ``True`` if the package is marked for upgrade.""" + return self._pcache._depcache.marked_upgrade(self._pkg) + + @property + def marked_delete(self) -> bool: + """Return ``True`` if the package is marked for delete.""" + return self._pcache._depcache.marked_delete(self._pkg) + + @property + def marked_keep(self) -> bool: + """Return ``True`` if the package is marked for keep.""" + return self._pcache._depcache.marked_keep(self._pkg) + + @property + def marked_downgrade(self) -> bool: + """Package is marked for downgrade""" + return self._pcache._depcache.marked_downgrade(self._pkg) + + @property + def marked_reinstall(self) -> bool: + """Return ``True`` if the package is marked for reinstall.""" + return self._pcache._depcache.marked_reinstall(self._pkg) + + @property + def is_installed(self) -> bool: + """Return ``True`` if the package is installed.""" + return self._pkg.current_ver is not None + + @property + def is_upgradable(self) -> bool: + """Return ``True`` if the package is upgradable.""" + return self.is_installed and self._pcache._depcache.is_upgradable(self._pkg) + + @property + def is_auto_removable(self) -> bool: + """Return ``True`` if the package is no longer required. + + If the package has been installed automatically as a dependency of + another package, and if no packages depend on it anymore, the package + is no longer required. + """ + return ( + self.is_installed or self.marked_install + ) and self._pcache._depcache.is_garbage(self._pkg) + + @property + def is_auto_installed(self) -> bool: + """Return whether the package is marked as automatically installed.""" + return self._pcache._depcache.is_auto_installed(self._pkg) + + @property + def phasing_applied(self) -> bool: + """Return ``True`` if the package update is being phased.""" + return self._pcache._depcache.phasing_applied(self._pkg) + + # sizes + + @property + def installed_files(self) -> list[str]: + """Return a list of files installed by the package. + + Return a list of unicode names of the files which have + been installed by this package + """ + for name in self.name, self.fullname: + path = "/var/lib/dpkg/info/%s.list" % name + try: + with open(path, "rb") as file_list: + return file_list.read().decode("utf-8").strip().split("\n") + except OSError: + continue + + return [] + + def get_changelog( + self, uri: str | None = None, cancel_lock: threading.Event | None = None + ) -> str: + """ + Download the changelog of the package and return it as unicode + string. + + The parameter *uri* refers to the uri of the changelog file. It may + contain multiple named variables which will be substitued. These + variables are (src_section, prefix, src_pkg, src_ver). An example is + the Ubuntu changelog:: + + "http://changelogs.ubuntu.com/changelogs/pool" \\ + "/%(src_section)s/%(prefix)s/%(src_pkg)s" \\ + "/%(src_pkg)s_%(src_ver)s/changelog" + + The parameter *cancel_lock* refers to an instance of threading.Event, + which if set, prevents the download. + """ + # Return a cached changelog if available + if self._changelog != "": + return self._changelog + + if not self.candidate: + return _("The list of changes is not available") + + if uri is None: + if self.candidate.origins[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 self.candidate.origins[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: + res = _("The list of changes is not available") + if isinstance(res, str): + return res + else: + return res.decode("utf-8") + + # get the src package name + src_pkg = self.candidate.source_name + + # assume "main" section + src_section = "main" + # use the section of the candidate as a starting point + section = self.candidate.section + + # get the source version + src_ver = self.candidate.source_version + + 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.SourceRecords() + except SystemError: + pass + else: + while src_records.lookup(src_pkg): + if not src_records.version: + continue + if self.candidate.source_version == src_records.version: + # Direct match, use it and do not do more lookups. + src_ver = src_records.version + section = src_records.section + break + if apt_pkg.version_compare(src_records.version, src_ver) > 0: + # The version is higher, it seems to match. + src_ver = src_records.version + section = src_records.section + + section_split = section.split("/", 1) + if len(section_split) > 1: + src_section = section_split[0] + del section_split + + # lib is handled special + prefix = src_pkg[0] + if src_pkg.startswith("lib"): + prefix = "lib" + src_pkg[3] + + # stip epoch + src_ver_split = src_ver.split(":", 1) + if len(src_ver_split) > 1: + src_ver = "".join(src_ver_split[1:]) + del src_ver_split + + uri = uri % { + "src_section": src_section, + "prefix": prefix, + "src_pkg": src_pkg, + "src_ver": src_ver, + } + + timeout = socket.getdefaulttimeout() + + # FIXME: when python2.4 vanishes from the archive, + # merge this into a single try..finally block (pep 341) + try: + try: + # Set a timeout for the changelog download + socket.setdefaulttimeout(2) + + # Check if the download was canceled + if cancel_lock and cancel_lock.is_set(): + return "" + # FIXME: python3.2: Should be closed manually + changelog_file = urlopen(uri) + # do only get the lines that are new + changelog = "" + regexp = "^%s \\((.*)\\)(.*)$" % (re.escape(src_pkg)) + while True: + # Check if the download was canceled + if cancel_lock and cancel_lock.is_set(): + return "" + # Read changelog line by line + line_raw = changelog_file.readline() + if not 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 = getattr(self.installed, "version", None) + 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.version_compare(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") + if not isinstance(changelog, str): + changelog = changelog.decode("utf-8") + self._changelog = changelog + + except HTTPError: + if self.candidate.origins[0].origin == "Ubuntu": + res = _( + "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) + else: + res = _("The list of changes is not available") + if isinstance(res, str): + return res + else: + return res.decode("utf-8") + except (OSError, BadStatusLine): + res = _( + "Failed to download the list of changes. \nPlease " + "check your Internet connection." + ) + if isinstance(res, str): + return res + else: + return res.decode("utf-8") + finally: + socket.setdefaulttimeout(timeout) + return self._changelog + + @property + def versions(self) -> VersionList: + """Return a VersionList() object for all available versions. + + .. versionadded:: 0.7.9 + """ + return VersionList(self) + + @property + def is_inst_broken(self) -> bool: + """Return True if the to-be-installed package is broken.""" + return self._pcache._depcache.is_inst_broken(self._pkg) + + @property + def is_now_broken(self) -> bool: + """Return True if the installed package is broken.""" + return self._pcache._depcache.is_now_broken(self._pkg) + + @property + def has_config_files(self) -> bool: + """Checks whether the package is is the config-files state.""" + return self._pkg.current_state == apt_pkg.CURSTATE_CONFIG_FILES + + # depcache actions + + def mark_keep(self) -> None: + """Mark a package for keep.""" + self._pcache.cache_pre_change() + self._pcache._depcache.mark_keep(self._pkg) + self._pcache.cache_post_change() + + def mark_delete(self, auto_fix: bool = True, purge: bool = False) -> None: + """Mark a package for deletion. + + If *auto_fix* is ``True``, the resolver will be run, trying to fix + broken packages. This is the default. + + If *purge* is ``True``, remove the configuration files of the package + as well. The default is to keep the configuration. + """ + self._pcache.cache_pre_change() + self._pcache._depcache.mark_delete(self._pkg, purge) + # try to fix broken stuffsta + if auto_fix and self._pcache._depcache.broken_count > 0: + fix = apt_pkg.ProblemResolver(self._pcache._depcache) + fix.clear(self._pkg) + fix.protect(self._pkg) + fix.remove(self._pkg) + fix.resolve() + self._pcache.cache_post_change() + + def mark_install( + self, auto_fix: bool = True, auto_inst: bool = True, from_user: bool = True + ) -> None: + """Mark a package for install. + + If *autoFix* is ``True``, the resolver will be run, trying to fix + broken packages. This is the default. + + If *autoInst* is ``True``, the dependencies of the packages will be + installed automatically. This is the default. + + If *fromUser* is ``True``, this package will not be marked as + automatically installed. This is the default. Set it to False if you + want to be able to automatically remove the package at a later stage + when no other package depends on it. + """ + self._pcache.cache_pre_change() + self._pcache._depcache.mark_install(self._pkg, auto_inst, from_user) + # try to fix broken stuff + if auto_fix and self._pcache._depcache.broken_count > 0: + fixer = apt_pkg.ProblemResolver(self._pcache._depcache) + fixer.clear(self._pkg) + fixer.protect(self._pkg) + fixer.resolve(True) + self._pcache.cache_post_change() + + def mark_upgrade(self, from_user: bool = True) -> None: + """Mark a package for upgrade.""" + if self.is_upgradable: + auto = self.is_auto_installed + self.mark_install(from_user=from_user) + self.mark_auto(auto) + else: + # FIXME: we may want to throw a exception here + sys.stderr.write( + ("MarkUpgrade() called on a non-upgradeable pkg: " "'%s'\n") + % self._pkg.name + ) + + def mark_auto(self, auto: bool = True) -> None: + """Mark a package as automatically installed. + + Call this function to mark a package as automatically installed. If the + optional parameter *auto* is set to ``False``, the package will not be + marked as automatically installed anymore. The default is ``True``. + """ + self._pcache._depcache.mark_auto(self._pkg, auto) + + def commit(self, fprogress: AcquireProgress, iprogress: InstallProgress) -> None: + """Commit the changes. + + The parameter *fprogress* refers to a apt_pkg.AcquireProgress() object, + like apt.progress.text.AcquireProgress(). + + The parameter *iprogress* refers to an InstallProgress() object, as + found in apt.progress.base. + """ + self._pcache._depcache.commit(fprogress, iprogress) + + +@no_type_check +def _test(): + """Self-test.""" + print("Self-test for the Package modul") + import random + + apt_pkg.init() + progress = apt.progress.text.OpProgress() + cache = apt.Cache(progress) + pkg = cache["apt-utils"] + print("Name: %s " % pkg.name) + print("ID: %s " % pkg.id) + print("Priority (Candidate): %s " % pkg.candidate.priority) + print("Priority (Installed): %s " % pkg.installed.priority) + print("Installed: %s " % pkg.installed.version) + print("Candidate: %s " % pkg.candidate.version) + print("CandidateDownloadable: %s" % pkg.candidate.downloadable) + print("CandidateOrigins: %s" % pkg.candidate.origins) + print("SourcePkg: %s " % pkg.candidate.source_name) + print("Section: %s " % pkg.section) + print("Summary: %s" % pkg.candidate.summary) + print("Description (formatted) :\n%s" % pkg.candidate.description) + print("Description (unformatted):\n%s" % pkg.candidate.raw_description) + print("InstalledSize: %s " % pkg.candidate.installed_size) + print("PackageSize: %s " % pkg.candidate.size) + print("Dependencies: %s" % pkg.installed.dependencies) + print("Recommends: %s" % pkg.installed.recommends) + for dep in pkg.candidate.dependencies: + print( + ",".join( + f"{o.name} ({o.version}) ({o.relation}) ({o.pre_depend})" + for o in dep.or_dependencies + ) + ) + print("arch: %s" % pkg.candidate.architecture) + print("homepage: %s" % pkg.candidate.homepage) + print("rec: ", pkg.candidate.record) + + print(cache["2vcard"].get_changelog()) + for i in True, False: + print("Running install on random upgradable pkgs with AutoFix: ", i) + for pkg in cache: + if pkg.is_upgradable: + if random.randint(0, 1) == 1: + pkg.mark_install(i) + print("Broken: %s " % cache._depcache.broken_count) + print("InstCount: %s " % cache._depcache.inst_count) + + print() + # get a new cache + for i in True, False: + print("Randomly remove some packages with AutoFix: %s" % i) + cache = apt.Cache(progress) + for name in cache.keys(): + if random.randint(0, 1) == 1: + try: + cache[name].mark_delete(i) + except SystemError: + print("Error trying to remove: %s " % name) + print("Broken: %s " % cache._depcache.broken_count) + print("DelCount: %s " % cache._depcache.del_count) + + +# self-test +if __name__ == "__main__": + _test() diff --git a/apt/progress/__init__.py b/apt/progress/__init__.py new file mode 100644 index 0000000..d1687d5 --- /dev/null +++ b/apt/progress/__init__.py @@ -0,0 +1,28 @@ +# apt/progress/__init__.py - Initialization file for apt.progress. +# +# Copyright (c) 2009 Julian Andres Klode +# +# 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 +"""Progress reporting. + +This package provides progress reporting for the python-apt package. The module +'base' provides classes with no output, and the module 'text' provides classes +for terminals, etc. +""" + +from collections.abc import Sequence + +__all__: Sequence[str] = [] diff --git a/apt/progress/base.py b/apt/progress/base.py new file mode 100644 index 0000000..ede5e5c --- /dev/null +++ b/apt/progress/base.py @@ -0,0 +1,332 @@ +# apt/progress/base.py - Base classes for progress reporting. +# +# Copyright (C) 2009 Julian Andres Klode +# +# 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 +# pylint: disable-msg = R0201 +"""Base classes for progress reporting. + +Custom progress classes should inherit from these classes. They can also be +used as dummy progress classes which simply do nothing. +""" +from __future__ import annotations + +import errno +import fcntl +import io +import os +import re +import select +import sys + +import apt_pkg + +__all__ = ["AcquireProgress", "CdromProgress", "InstallProgress", "OpProgress"] + + +class AcquireProgress: + """Monitor object for downloads controlled by the Acquire class. + + This is an mostly abstract class. You should subclass it and implement the + methods to get something useful. + """ + + current_bytes = current_cps = fetched_bytes = last_bytes = total_bytes = 0.0 + current_items = elapsed_time = total_items = 0 + + def done(self, item: apt_pkg.AcquireItemDesc) -> None: + """Invoked when an item is successfully and completely fetched.""" + + def fail(self, item: apt_pkg.AcquireItemDesc) -> None: + """Invoked when an item could not be fetched.""" + + def fetch(self, item: apt_pkg.AcquireItemDesc) -> None: + """Invoked when some of the item's data is fetched.""" + + def ims_hit(self, item: apt_pkg.AcquireItemDesc) -> None: + """Invoked when an item is confirmed to be up-to-date. + + Invoked when an item is confirmed to be up-to-date. For instance, + when an HTTP download is informed that the file on the server was + not modified. + """ + + def media_change(self, media: str, drive: str) -> bool: + """Prompt the user to change the inserted removable media. + + The parameter 'media' decribes the name of the media type that + should be changed, whereas the parameter 'drive' should be the + identifying name of the drive whose media should be changed. + + This method should not return until the user has confirmed to the user + interface that the media change is complete. It must return True if + the user confirms the media change, or False to cancel it. + """ + return False + + def pulse(self, owner: apt_pkg.Acquire) -> bool: + """Periodically invoked while the Acquire process is underway. + + This method gets invoked while the Acquire progress given by the + parameter 'owner' is underway. It should display information about + the current state. + + This function returns a boolean value indicating whether the + acquisition should be continued (True) or cancelled (False). + """ + return True + + def start(self) -> None: + """Invoked when the Acquire process starts running.""" + # Reset all our values. + self.current_bytes = 0.0 + self.current_cps = 0.0 + self.current_items = 0 + self.elapsed_time = 0 + self.fetched_bytes = 0.0 + self.last_bytes = 0.0 + self.total_bytes = 0.0 + self.total_items = 0 + + def stop(self) -> None: + """Invoked when the Acquire process stops running.""" + + +class CdromProgress: + """Base class for reporting the progress of adding a cdrom. + + Can be used with apt_pkg.Cdrom to produce an utility like apt-cdrom. The + attribute 'total_steps' defines the total number of steps and can be used + in update() to display the current progress. + """ + + total_steps = 0 + + def ask_cdrom_name(self) -> str | None: + """Ask for the name of the cdrom. + + If a name has been provided, return it. Otherwise, return None to + cancel the operation. + """ + + def change_cdrom(self) -> bool: + """Ask for the CD-ROM to be changed. + + Return True once the cdrom has been changed or False to cancel the + operation. + """ + return False + + def update(self, text: str, current: int) -> None: + """Periodically invoked to update the interface. + + The string 'text' defines the text which should be displayed. The + integer 'current' defines the number of completed steps. + """ + + +class InstallProgress: + """Class to report the progress of installing packages.""" + + child_pid, percent, select_timeout, status = 0, 0.0, 0.1, "" + + def __init__(self) -> None: + (self.statusfd, self.writefd) = os.pipe() + # These will leak fds, but fixing this safely requires API changes. + self.write_stream: io.TextIOBase = os.fdopen(self.writefd, "w") + self.status_stream: io.TextIOBase = os.fdopen(self.statusfd, "r") # noqa + fcntl.fcntl(self.statusfd, fcntl.F_SETFL, os.O_NONBLOCK) + + def start_update(self) -> None: + """(Abstract) Start update.""" + + def finish_update(self) -> None: + """(Abstract) Called when update has finished.""" + + def __enter__(self) -> InstallProgress: + return self + + def __exit__(self, type: object, value: object, traceback: object) -> None: + self.write_stream.close() + self.status_stream.close() + + def error(self, pkg: str, errormsg: str) -> None: + """(Abstract) Called when a error is detected during the install.""" + + def conffile(self, current: str, new: str) -> None: + """(Abstract) Called when a conffile question from dpkg is detected.""" + + def status_change(self, pkg: str, percent: float, status: str) -> None: + """(Abstract) Called when the APT status changed.""" + + def dpkg_status_change(self, pkg: str, status: str) -> None: + """(Abstract) Called when the dpkg status changed.""" + + def processing(self, pkg: str, stage: str) -> None: + """(Abstract) Sent just before a processing stage starts. + + The parameter 'stage' is one of "upgrade", "install" + (both sent before unpacking), "configure", "trigproc", "remove", + "purge". This method is used for dpkg only. + """ + + def run(self, obj: apt_pkg.PackageManager | bytes | str) -> int: + """Install using the object 'obj'. + + This functions runs install actions. The parameter 'obj' may either + be a PackageManager object in which case its do_install() method is + called or the path to a deb file. + + If the object is a PackageManager, the functions returns the result + of calling its do_install() method. Otherwise, the function returns + the exit status of dpkg. In both cases, 0 means that there were no + problems. + """ + pid = self.fork() + if pid == 0: + try: + # PEP-446 implemented in Python 3.4 made all descriptors + # CLOEXEC, but we need to be able to pass writefd to dpkg + # when we spawn it + os.set_inheritable(self.writefd, True) + except AttributeError: # if we don't have os.set_inheritable() + pass + # pm.do_install might raise a exception, + # when this happens, we need to catch + # it, otherwise os._exit() is not run + # and the execution continues in the + # parent code leading to very confusing bugs + try: + os._exit(obj.do_install(self.write_stream.fileno())) # type: ignore # noqa + except AttributeError: + os._exit( + os.spawnlp( + os.P_WAIT, + "dpkg", + "dpkg", + "--status-fd", + str(self.write_stream.fileno()), + "-i", + obj, # type: ignore # noqa + ) + ) + except Exception as e: + sys.stderr.write("%s\n" % e) + os._exit(apt_pkg.PackageManager.RESULT_FAILED) + + self.child_pid = pid + res = self.wait_child() + return os.WEXITSTATUS(res) + + def fork(self) -> int: + """Fork.""" + return os.fork() + + def update_interface(self) -> None: + """Update the interface.""" + try: + line = self.status_stream.readline() + except OSError as err: + # resource temporarly unavailable is ignored + if err.errno != errno.EAGAIN and err.errno != errno.EWOULDBLOCK: + print(err.strerror) + return + + pkgname = status = status_str = percent = base = "" + + if line.startswith("pm"): + try: + (status, pkgname, percent, status_str) = line.split(":", 3) + except ValueError: + # silently ignore lines that can't be parsed + return + elif line.startswith("status"): + try: + (base, pkgname, status, status_str) = line.split(":", 3) + except ValueError: + (base, pkgname, status) = line.split(":", 2) + elif line.startswith("processing"): + (status, status_str, pkgname) = line.split(":", 2) + self.processing(pkgname.strip(), status_str.strip()) + + # Always strip the status message + pkgname = pkgname.strip() + status_str = status_str.strip() + status = status.strip() + + if status == "pmerror" or status == "error": + self.error(pkgname, status_str) + elif status == "conffile-prompt" or status == "pmconffile": + match = re.match("\\s*'(.*)'\\s*'(.*)'.*", status_str) + if match: + self.conffile(match.group(1), match.group(2)) + elif status == "pmstatus": + # FIXME: Float comparison + if float(percent) != self.percent or status_str != self.status: + self.status_change(pkgname, float(percent), status_str.strip()) + self.percent = float(percent) + self.status = status_str.strip() + elif base == "status": + self.dpkg_status_change(pkgname, status) + + def wait_child(self) -> int: + """Wait for child progress to exit. + + This method is responsible for calling update_interface() from time to + time. It exits once the child has exited. The return values is the + full status returned from os.waitpid() (not only the return code). + """ + (pid, res) = (0, 0) + while True: + try: + select.select([self.status_stream], [], [], self.select_timeout) + except OSError as error: + (errno_, _errstr) = error.args + if errno_ != errno.EINTR: + raise + + self.update_interface() + try: + (pid, res) = os.waitpid(self.child_pid, os.WNOHANG) + if pid == self.child_pid: + break + except OSError as err: + if err.errno == errno.ECHILD: + break + if err.errno != errno.EINTR: + raise + + return res + + +class OpProgress: + """Monitor objects for operations. + + Display the progress of operations such as opening the cache.""" + + major_change, op, percent, subop = False, "", 0.0, "" + + def update(self, percent: float | None = None) -> None: + """Called periodically to update the user interface. + + You may use the optional argument 'percent' to set the attribute + 'percent' in this call. + """ + if percent is not None: + self.percent = percent + + def done(self) -> None: + """Called once an operation has been completed.""" diff --git a/apt/progress/text.py b/apt/progress/text.py new file mode 100644 index 0000000..ea1a176 --- /dev/null +++ b/apt/progress/text.py @@ -0,0 +1,294 @@ +# Copyright (c) 2009 Julian Andres Klode +# +# 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 +"""Progress reporting for text interfaces.""" +import io +import os +import signal +import sys +import types +from collections.abc import Callable + +import apt_pkg + +from apt.progress import base + +__all__ = ["AcquireProgress", "CdromProgress", "OpProgress"] + + +def _(msg: str) -> str: + """Translate the message, also try apt if translation is missing.""" + res = apt_pkg.gettext(msg) + if res == msg: + res = apt_pkg.gettext(msg, "apt") + return res + + +class TextProgress: + """Internal Base class for text progress classes.""" + + def __init__(self, outfile: io.TextIOBase | None = None) -> None: + self._file = outfile or sys.stdout + self._width = 0 + + def _write(self, msg: str, newline: bool = True, maximize: bool = False) -> None: + """Write the message on the terminal, fill remaining space.""" + self._file.write("\r") + self._file.write(msg) + + # Fill remaining stuff with whitespace + if self._width > len(msg): + self._file.write((self._width - len(msg)) * " ") + elif maximize: # Needed for OpProgress. + self._width = max(self._width, len(msg)) + if newline: + self._file.write("\n") + else: + # self._file.write("\r") + self._file.flush() + + +class OpProgress(base.OpProgress, TextProgress): + """Operation progress reporting. + + This closely resembles OpTextProgress in libapt-pkg. + """ + + def __init__(self, outfile: io.TextIOBase | None = None) -> None: + TextProgress.__init__(self, outfile) + base.OpProgress.__init__(self) + self.old_op = "" + + def update(self, percent: float | None = None) -> None: + """Called periodically to update the user interface.""" + base.OpProgress.update(self, percent) + if self.major_change and self.old_op: + self._write(self.old_op) + self._write("%s... %i%%\r" % (self.op, self.percent), False, True) + self.old_op = self.op + + def done(self) -> None: + """Called once an operation has been completed.""" + base.OpProgress.done(self) + if self.old_op: + self._write(_("%c%s... Done") % ("\r", self.old_op), True, True) + self.old_op = "" + + +class AcquireProgress(base.AcquireProgress, TextProgress): + """AcquireProgress for the text interface.""" + + def __init__(self, outfile: io.TextIOBase | None = None) -> None: + TextProgress.__init__(self, outfile) + base.AcquireProgress.__init__(self) + self._signal: ( + Callable[[int, types.FrameType | None], None] | int | signal.Handlers | None + ) = None # noqa + self._width = 80 + self._id = 1 + + def start(self) -> None: + """Start an Acquire progress. + + In this case, the function sets up a signal handler for SIGWINCH, i.e. + window resize signals. And it also sets id to 1. + """ + base.AcquireProgress.start(self) + self._signal = signal.signal(signal.SIGWINCH, self._winch) + # Get the window size. + self._winch() + self._id = 1 + + def _winch(self, *dummy: object) -> None: + """Signal handler for window resize signals.""" + if hasattr(self._file, "fileno") and os.isatty(self._file.fileno()): + import fcntl + import struct + import termios + + buf = fcntl.ioctl(self._file, termios.TIOCGWINSZ, 8 * b" ") # noqa + dummy, col, dummy, dummy = struct.unpack("hhhh", buf) + self._width = col - 1 # 1 for the cursor + + def ims_hit(self, item: apt_pkg.AcquireItemDesc) -> None: + """Called when an item is update (e.g. not modified on the server).""" + base.AcquireProgress.ims_hit(self, item) + line = _("Hit ") + item.description + if item.owner.filesize: + line += " [%sB]" % apt_pkg.size_to_str(item.owner.filesize) + self._write(line) + + def fail(self, item: apt_pkg.AcquireItemDesc) -> None: + """Called when an item is failed.""" + base.AcquireProgress.fail(self, item) + if item.owner.status == item.owner.STAT_DONE: + self._write(_("Ign ") + item.description) + else: + self._write(_("Err ") + item.description) + self._write(" %s" % item.owner.error_text) + + def fetch(self, item: apt_pkg.AcquireItemDesc) -> None: + """Called when some of the item's data is fetched.""" + base.AcquireProgress.fetch(self, item) + # It's complete already (e.g. Hit) + if item.owner.complete: + return + item.owner.id = self._id + self._id += 1 + line = _("Get:") + f"{item.owner.id} {item.description}" + if item.owner.filesize: + line += " [%sB]" % apt_pkg.size_to_str(item.owner.filesize) + + self._write(line) + + def pulse(self, owner: apt_pkg.Acquire) -> bool: + """Periodically invoked while the Acquire process is underway. + + Return False if the user asked to cancel the whole Acquire process.""" + base.AcquireProgress.pulse(self, owner) + # only show progress on a tty to not clutter log files etc + if hasattr(self._file, "fileno") and not os.isatty(self._file.fileno()): + return True + + # calculate progress + percent = ((self.current_bytes + self.current_items) * 100.0) / float( + self.total_bytes + self.total_items + ) + + shown = False + tval = "%i%%" % percent + end = "" + if self.current_cps: + eta = int(float(self.total_bytes - self.current_bytes) / self.current_cps) + end = " {}B/s {}".format( + apt_pkg.size_to_str(self.current_cps), + apt_pkg.time_to_str(eta), + ) + + for worker in owner.workers: + val = "" + if not worker.current_item: + if worker.status: + val = " [%s]" % worker.status + if len(tval) + len(val) + len(end) >= self._width: + break + tval += val + shown = True + continue + shown = True + + if worker.current_item.owner.id: + val += " [%i %s" % ( + worker.current_item.owner.id, + worker.current_item.shortdesc, + ) + else: + val += " [%s" % worker.current_item.description + if worker.current_item.owner.active_subprocess: + val += " %s" % worker.current_item.owner.active_subprocess + + val += " %sB" % apt_pkg.size_to_str(worker.current_size) + + # Add the total size and percent + if worker.total_size and not worker.current_item.owner.complete: + val += "/%sB %i%%" % ( + apt_pkg.size_to_str(worker.total_size), + worker.current_size * 100.0 / worker.total_size, + ) + + val += "]" + + if len(tval) + len(val) + len(end) >= self._width: + # Display as many items as screen width + break + else: + tval += val + + if not shown: + tval += _(" [Working]") + + if self.current_cps: + tval += (self._width - len(end) - len(tval)) * " " + end + + self._write(tval, False) + return True + + def media_change(self, medium: str, drive: str) -> bool: + """Prompt the user to change the inserted removable media.""" + base.AcquireProgress.media_change(self, medium, drive) + self._write( + _( + "Media change: please insert the disc labeled\n" + " '%s'\n" + "in the drive '%s' and press enter\n" + ) + % (medium, drive) + ) + return input() not in ("c", "C") + + def stop(self) -> None: + """Invoked when the Acquire process stops running.""" + base.AcquireProgress.stop(self) + # Trick for getting a translation from apt + self._write( + ( + _("Fetched %sB in %s (%sB/s)\n") + % ( + apt_pkg.size_to_str(self.fetched_bytes), + apt_pkg.time_to_str(self.elapsed_time), + apt_pkg.size_to_str(self.current_cps), + ) + ).rstrip("\n") + ) + + # Delete the signal again. + import signal + + signal.signal(signal.SIGWINCH, self._signal) + + +class CdromProgress(base.CdromProgress, TextProgress): + """Text CD-ROM progress.""" + + def ask_cdrom_name(self) -> str | None: + """Ask the user to provide a name for the disc.""" + base.CdromProgress.ask_cdrom_name(self) + self._write( + _( + "Please provide a name for this medium, such as " + "'Debian 2.1r1 Disk 1'" + ), + False, + ) + try: + return str(input(":")) + except KeyboardInterrupt: + return None + + def update(self, text: str, current: int) -> None: + """Set the current progress.""" + base.CdromProgress.update(self, text, current) + if text: + self._write(text, False) + + def change_cdrom(self) -> bool: + """Ask the user to change the CD-ROM.""" + base.CdromProgress.change_cdrom(self) + self._write(_("Please insert an installation medium and press enter"), False) + try: + return bool(input() == "") + except KeyboardInterrupt: + return False diff --git a/apt/py.typed b/apt/py.typed new file mode 100644 index 0000000..e69de29 diff --git a/apt/utils.py b/apt/utils.py new file mode 100644 index 0000000..5b1fd46 --- /dev/null +++ b/apt/utils.py @@ -0,0 +1,100 @@ +# Copyright (C) 2009 Canonical +# +# Authors: +# Michael Vogt +# +# 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., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +import datetime +import os + +import apt_pkg + +import apt + + +def get_maintenance_end_date( + release_date: datetime.datetime, m_months: int +) -> tuple[int, int]: + """ + get the (year, month) tuple when the maintenance for the distribution + ends. Needs the data of the release and the number of months that + its is supported as input + """ + # calc end date + years = m_months // 12 + months = m_months % 12 + support_end_year = release_date.year + years + (release_date.month + months) // 12 + support_end_month = (release_date.month + months) % 12 + # special case: this happens when e.g. doing 2010-06 + 18 months + if support_end_month == 0: + support_end_month = 12 + support_end_year -= 1 + return (support_end_year, support_end_month) + + +def get_release_date_from_release_file(path: str) -> int | None: + """ + return the release date as time_t for the given release file + """ + if not path or not os.path.exists(path): + return None + + with os.fdopen(apt_pkg.open_maybe_clear_signed_file(path)) as data: + tag = apt_pkg.TagFile(data) + section = next(tag) + if "Date" not in section: + return None + date = section["Date"] + return apt_pkg.str_to_time(date) + + +def get_release_filename_for_pkg( + cache: apt.Cache, pkgname: str, label: str, release: str +) -> str | None: + "get the release file that provides this pkg" + if pkgname not in cache: + return None + pkg = cache[pkgname] + ver = None + # look for the version that comes from the repos with + # the given label and origin + for aver in pkg._pkg.version_list: + if aver is None or aver.file_list is None: + continue + for ver_file, _index in aver.file_list: + # print verFile + if ( + ver_file.origin == label + and ver_file.label == label + and ver_file.archive == release + ): + ver = aver + if not ver: + return None + indexfile = cache._list.find_index(ver.file_list[0][0]) + for metaindex in cache._list.list: + for m in metaindex.index_files: + if indexfile and indexfile.describe == m.describe and indexfile.is_trusted: + dirname = apt_pkg.config.find_dir("Dir::State::lists") + for relfile in ["InRelease", "Release"]: + name = apt_pkg.uri_to_filename( + metaindex.uri + ) + "dists_{}_{}".format( + metaindex.dist, + relfile, + ) + if os.path.exists(dirname + name): + return dirname + name + return None diff --git a/aptsources/__init__.py b/aptsources/__init__.py new file mode 100644 index 0000000..2ccf4fc --- /dev/null +++ b/aptsources/__init__.py @@ -0,0 +1,6 @@ +import apt_pkg + +# init the package system, but do not re-initialize config +if "APT" not in apt_pkg.config: + apt_pkg.init_config() +apt_pkg.init_system() diff --git a/aptsources/_deb822.py b/aptsources/_deb822.py new file mode 100644 index 0000000..d3b3a7c --- /dev/null +++ b/aptsources/_deb822.py @@ -0,0 +1,144 @@ +#!/usr/bin/python3 +# +# Copyright (C) Canonical Ltd +# +# SPDX-License-Identifier: GPL-2.0+ + +"""deb822 parser with support for comment headers and footers.""" + +import collections +import io +import typing + +import apt_pkg + +T = typing.TypeVar("T") + + +class Section: + """A single deb822 section, possibly with comments. + + This represents a single deb822 section. + """ + + tags: collections.OrderedDict[str, str] + _case_mapping: dict[str, str] + header: str + footer: str + + def __init__(self, section: typing.Union[str, "Section"]): + if isinstance(section, Section): + self.tags = collections.OrderedDict(section.tags) + self._case_mapping = {k.casefold(): k for k in self.tags} + self.header = section.header + self.footer = section.footer + return + + comments = ["", ""] + in_section = False + trimmed_section = "" + + for line in section.split("\n"): + if line.startswith("#"): + # remove the leading # + line = line[1:] + comments[in_section] += line + "\n" + continue + + in_section = True + trimmed_section += line + "\n" + + self.tags = collections.OrderedDict(apt_pkg.TagSection(trimmed_section)) + self._case_mapping = {k.casefold(): k for k in self.tags} + self.header, self.footer = comments + + def __getitem__(self, key: str) -> str: + """Get the value of a field.""" + return self.tags[self._case_mapping.get(key.casefold(), key)] + + def __delitem__(self, key: str) -> None: + """Delete a field""" + del self.tags[self._case_mapping.get(key.casefold(), key)] + + def __setitem__(self, key: str, val: str) -> None: + """Set the value of a field.""" + if key.casefold() not in self._case_mapping: + self._case_mapping[key.casefold()] = key + self.tags[self._case_mapping[key.casefold()]] = val + + def __bool__(self) -> bool: + return bool(self.tags) + + @typing.overload + def get(self, key: str) -> str | None: + ... + + @typing.overload + def get(self, key: str, default: T) -> T | str: + ... + + def get(self, key: str, default: T | None = None) -> T | None | str: + try: + return self[key] + except KeyError: + return default + + @staticmethod + def __comment_lines(content: str) -> str: + return ( + "\n".join("#" + line for line in content.splitlines()) + "\n" + if content + else "" + ) + + def __str__(self) -> str: + """Canonical string rendering of this section.""" + return ( + self.__comment_lines(self.header) + + "".join(f"{k}: {v}\n" for k, v in self.tags.items()) + + self.__comment_lines(self.footer) + ) + + +class File: + """ + Parse a given file object into a list of Section objects. + """ + + def __init__(self, fobj: io.TextIOBase): + self.sections = [] + section = "" + for line in fobj: + if not line.isspace(): + # A line is part of the section if it has non-whitespace characters + section += line + elif section: + # Our line is just whitespace and we have gathered section content, so let's write out the section + self.sections.append(Section(section)) + section = "" + + # The final section may not be terminated by an empty line + if section: + self.sections.append(Section(section)) + + def __iter__(self) -> typing.Iterator[Section]: + return iter(self.sections) + + def __str__(self) -> str: + return "\n".join(str(s) for s in self.sections) + + +if __name__ == "__main__": + st = """# Header +# More header +K1: V1 +# Inline +K2: V2 + # not a comment +# Footer +# More footer +""" + + s = Section(st) + + print(s) diff --git a/aptsources/distinfo.py b/aptsources/distinfo.py new file mode 100644 index 0000000..bd30f81 --- /dev/null +++ b/aptsources/distinfo.py @@ -0,0 +1,415 @@ +# distinfo.py - provide meta information for distro repositories +# +# Copyright (c) 2005 Gustavo Noronha Silva +# Copyright (c) 2006-2007 Sebastian Heinlein +# +# Authors: Gustavo Noronha Silva +# Sebastian Heinlein +# +# 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 + +import csv +import errno +import logging +import os +import re +from collections.abc import Iterator +from subprocess import PIPE, Popen +from typing import cast + +import apt_pkg +from apt_pkg import gettext as _ + + +def _expand_template(template: str, csv_path: str) -> Iterator[str]: + """Expand the given template. + + A template file consists of a header, followed by paragraphs + of templated suites, followed by a footer. A templated suite + is any paragraph where the Suite field contains {. + + This function expands all templated suites using the information + found in the CSV file supplied by distro-info-data. + + It yields lines of template info. + """ + + known_suites = set() + + # Copy out any header, and gather all hardcoded suites + with apt_pkg.TagFile(template) as tmpl: + for section in tmpl: + if "X-Exclude-Suites" in section: + known_suites.update(section["X-Exclude-Suites"].split(", ")) + if "Suite" in section: + if "{" in section["Suite"]: + break + + known_suites.add(section["Suite"]) + + yield from str(section).splitlines() + else: + # We did not break, so we did copy all of them + return + + for section in tmpl: + if "Suite" in section: + known_suites.add(section["Suite"]) + + with open(csv_path) as csv_object: + releases = reversed(list(csv.DictReader(csv_object))) + + # Perform template substitution on the middle of the list + for rel in releases: + if rel["series"] in known_suites: + continue + yield "" + rel["version"] = rel["version"].replace(" LTS", "") + with apt_pkg.TagFile(template) as tmpl: + for section in tmpl: + # Only work on template sections, this skips head and tails + if "Suite" not in section or "{" not in section["Suite"]: + continue + if "X-Version" in section: + # Version requirements. Maybe should be made nicer + ver = rel["version"] + if any( + ( + field.startswith("le") + and apt_pkg.version_compare(field[3:], ver) < 0 + ) + or ( + field.startswith("ge") + and apt_pkg.version_compare(field[3:], ver) > 0 + ) + for field in section["X-Version"].split(", ") + ): + continue + + for line in str(section).format(**rel).splitlines(): + if line.startswith("X-Version"): + continue + yield line + + # Copy out remaining suites + with apt_pkg.TagFile(template) as tmpl: + # Skip the head again, we don't want to copy it twice + for section in tmpl: + if "Suite" in section and "{" in section["Suite"]: + break + + for section in tmpl: + # Ignore any template parts and copy the rest out, + # this is the inverse of the template substitution loop + if "Suite" in section and "{" in section["Suite"]: + continue + + yield from str(section).splitlines() + + +class Template: + def __init__(self) -> None: + self.name: str | None = None + self.child = False + self.parents: list[Template] = [] # ref to parent template(s) + self.match_name: str | None = None + self.description: str | None = None + self.base_uri: str | None = None + self.type: str | None = None + self.components: list[Component] = [] + self.children: list[Template] = [] + self.match_uri: str | None = None + self.mirror_set: dict[str, Mirror] = {} + self.distribution: str | None = None + self.available = True + self.official = True + + def has_component(self, comp: str) -> bool: + """Check if the distribution provides the given component""" + return comp in (c.name for c in self.components) + + def is_mirror(self, url: str) -> bool: + """Check if a given url of a repository is a valid mirror""" + proto, hostname, dir = split_url(url) + if hostname in self.mirror_set: + return self.mirror_set[hostname].has_repository(proto, dir) + else: + return False + + +class Component: + def __init__( + self, + name: str, + desc: str | None = None, + long_desc: str | None = None, + parent_component: str | None = None, + ): + self.name = name + self.description = desc + self.description_long = long_desc + self.parent_component = parent_component + + def get_parent_component(self) -> str | None: + return self.parent_component + + def set_parent_component(self, parent: str) -> None: + self.parent_component = parent + + def get_description(self) -> str | None: + if self.description_long is not None: + return self.description_long + elif self.description is not None: + return self.description + else: + return None + + def set_description(self, desc: str) -> None: + self.description = desc + + def set_description_long(self, desc: str) -> None: + self.description_long = desc + + def get_description_long(self) -> str | None: + return self.description_long + + +class Mirror: + """Storage for mirror related information""" + + def __init__( + self, proto: str, hostname: str, dir: str, location: str | None = None + ): + self.hostname = hostname + self.repositories: list[Repository] = [] + self.add_repository(proto, dir) + self.location = location + + def add_repository(self, proto: str, dir: str) -> None: + self.repositories.append(Repository(proto, dir)) + + def get_repositories_for_proto(self, proto: str) -> list["Repository"]: + return [r for r in self.repositories if r.proto == proto] + + def has_repository(self, proto: str, dir: str) -> bool: + if dir is None: + return False + for r in self.repositories: + if r.proto == proto and dir in r.dir: + return True + return False + + def get_repo_urls(self) -> list[str]: + return [r.get_url(self.hostname) for r in self.repositories] + + def get_location(self) -> str | None: + return self.location + + def set_location(self, location: str) -> None: + self.location = location + + +class Repository: + def __init__(self, proto: str, dir: str) -> None: + self.proto = proto + self.dir = dir + + def get_info(self) -> tuple[str, str]: + return self.proto, self.dir + + def get_url(self, hostname: str) -> str: + return f"{self.proto}://{hostname}/{self.dir}" + + +def split_url(url: str) -> list[str]: + """split a given URL into the protocoll, the hostname and the dir part""" + split = re.split(":*\\/+", url, maxsplit=2) + while len(split) < 3: + split.append(None) + return split + + +class DistInfo: + def __init__( + self, + dist: str | None = None, + base_dir: str = "/usr/share/python-apt/templates", + ): + self.metarelease_uri = "" + self.templates: list[Template] = [] + self.arch = apt_pkg.config.find("APT::Architecture") + + location = None + match_loc = re.compile(r"^#LOC:(.+)$") + match_mirror_line = re.compile( + r"^(#LOC:.+)|(((http)|(ftp)|(rsync)|(file)|(mirror)|(https))://" + r"[A-Za-z0-9/\.:\-_@]+)$" + ) + # match_mirror_line = re.compile(r".+") + + if not dist: + try: + dist = ( + Popen( + ["lsb_release", "-i", "-s"], + universal_newlines=True, + stdout=PIPE, + ) + .communicate()[0] + .strip() + ) + except OSError as exc: + if exc.errno != errno.ENOENT: + logging.warning("lsb_release failed, using defaults: %s" % exc) + dist = "Debian" + + self.dist = dist + + map_mirror_sets = {} + + dist_fname = f"{base_dir}/{dist}.info" + csv_fname = f"/usr/share/distro-info/{dist.lower()}.csv" + + # FIXME: Logic doesn't work with types. + template = cast(Template, None) + component = cast(Component, None) + for line in _expand_template(dist_fname, csv_fname): + tokens = line.split(":", 1) + if len(tokens) < 2: + continue + field = tokens[0].strip() + value = tokens[1].strip() + if field == "ChangelogURI": + self.changelogs_uri = _(value) + elif field == "MetaReleaseURI": + self.metarelease_uri = value + elif field == "Suite": + self.finish_template(template, component) + component = cast(Component, None) # FIXME + template = Template() + template.name = value + template.distribution = dist + template.match_name = "^%s$" % value + elif field == "MatchName": + template.match_name = value + elif field == "ParentSuite": + template.child = True + for nanny in self.templates: + # look for parent and add back ref to it + if nanny.name == value: + template.parents.append(nanny) + nanny.children.append(template) + elif field == "Available": + template.available = apt_pkg.string_to_bool(value) + elif field == "Official": + template.official = apt_pkg.string_to_bool(value) + elif field == "RepositoryType": + template.type = value + elif field == "BaseURI" and not template.base_uri: + template.base_uri = value + elif field == "BaseURI-%s" % self.arch: + template.base_uri = value + elif field == "MatchURI" and not template.match_uri: + template.match_uri = value + elif field == "MatchURI-%s" % self.arch: + template.match_uri = value + elif field == "MirrorsFile" or field == "MirrorsFile-%s" % self.arch: + # Make the path absolute. + value = ( + os.path.isabs(value) + and value + or os.path.abspath(os.path.join(base_dir, value)) + ) + if value not in map_mirror_sets: + mirror_set: dict[str, Mirror] = {} + try: + with open(value) as value_f: + mirror_data = list( + filter( + match_mirror_line.match, + [x.strip() for x in value_f], + ) + ) + except Exception: + print(f"WARNING: Failed to read mirror file {value}") + mirror_data = [] + for line in mirror_data: + if line.startswith("#LOC:"): + location = match_loc.sub(r"\1", line) + continue + (proto, hostname, dir) = split_url(line) + if hostname in mirror_set: + mirror_set[hostname].add_repository(proto, dir) + else: + mirror_set[hostname] = Mirror( + proto, hostname, dir, location + ) + map_mirror_sets[value] = mirror_set + template.mirror_set = map_mirror_sets[value] + elif field == "Description": + template.description = _(value) + elif field == "Component": + if component and not template.has_component(component.name): + template.components.append(component) + component = Component(value) + elif field == "CompDescription": + component.set_description(_(value)) + elif field == "CompDescriptionLong": + component.set_description_long(_(value)) + elif field == "ParentComponent": + component.set_parent_component(value) + self.finish_template(template, component) + template = cast(Template, None) + component = cast(Component, None) + + def finish_template(self, template: Template, component: Component | None) -> None: + "finish the current tempalte" + if not template: + return + # reuse some properties of the parent template + if template.match_uri is None and template.child: + for t in template.parents: + if t.match_uri: + template.match_uri = t.match_uri + break + if template.mirror_set == {} and template.child: + for t in template.parents: + if t.match_uri: + template.mirror_set = t.mirror_set + break + if component and not template.has_component(component.name): + template.components.append(component) + component = None + # the official attribute is inherited + for t in template.parents: + template.official = t.official + self.templates.append(template) + + +if __name__ == "__main__": + d = DistInfo("Ubuntu", "/usr/share/python-apt/templates") + logging.info(d.changelogs_uri) + for template in d.templates: + logging.info("\nSuite: %s" % template.name) + logging.info("Desc: %s" % template.description) + logging.info("BaseURI: %s" % template.base_uri) + logging.info("MatchURI: %s" % template.match_uri) + if template.mirror_set != {}: + logging.info("Mirrors: %s" % list(template.mirror_set.keys())) + for comp in template.components: + logging.info(f" {comp.name} -{comp.description} -{comp.description_long}") + for child in template.children: + logging.info(" %s" % child.description) diff --git a/aptsources/distro.py b/aptsources/distro.py new file mode 100644 index 0000000..546d0e7 --- /dev/null +++ b/aptsources/distro.py @@ -0,0 +1,648 @@ +# distro.py - Provide a distro abstraction of the sources.list +# +# Copyright (c) 2004-2009 Canonical Ltd. +# Copyright (c) 2006-2007 Sebastian Heinlein +# Copyright (c) 2016 Harald Sitter +# +# Authors: Sebastian Heinlein +# Michael Vogt +# Harald Sitter +# +# 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 + +import gettext +import logging +import os +import re +import shlex +import warnings +from xml.etree.ElementTree import ElementTree + +from apt_pkg import gettext as _ + + +class NoDistroTemplateException(Exception): + pass + + +class Distribution: + def __init__(self, id, codename, description, release, is_like=[]): + """Container for distribution specific informations""" + # LSB information + self.id = id + self.codename = codename + self.description = description + self.release = release + self.is_like = is_like + + self.binary_type = "deb" + self.source_type = "deb-src" + + def get_sources(self, sourceslist): + """ + Find the corresponding template, main and child sources + for the distribution + """ + + self.sourceslist = sourceslist + # corresponding sources + self.source_template = None + self.child_sources = [] + self.main_sources = [] + self.disabled_sources = [] + self.cdrom_sources = [] + self.download_comps = [] + self.enabled_comps = [] + self.cdrom_comps = [] + self.used_media = [] + self.get_source_code = False + self.source_code_sources = [] + + # location of the sources + self.default_server = "" + self.main_server = "" + self.nearest_server = "" + self.used_servers = [] + + # find the distro template + for template in self.sourceslist.matcher.templates: + if self.is_codename(template.name) and template.distribution == self.id: + # print "yeah! found a template for %s" % self.description + # print template.description, template.base_uri, \ + # template.components + self.source_template = template + break + if self.source_template is None: + raise NoDistroTemplateException( + "Error: could not find a distribution template for %s/%s" + % (self.id, self.codename) + ) + + # find main and child sources + media = [] + comps = [] + cdrom_comps = [] + enabled_comps = [] + # source_code = [] + for source in self.sourceslist.exploded_list(): + if ( + not source.invalid + and self.is_codename(source.dist) + and source.template + and source.template.official + and self.is_codename(source.template.name) + ): + # print "yeah! found a distro repo: %s" % source.line + # cdroms need do be handled differently + if source.uri.startswith("cdrom:") and not source.disabled: + self.cdrom_sources.append(source) + cdrom_comps.extend(source.comps) + elif source.uri.startswith("cdrom:") and source.disabled: + self.cdrom_sources.append(source) + elif source.type == self.binary_type and not source.disabled: + self.main_sources.append(source) + comps.extend(source.comps) + media.append(source.uri) + elif source.type == self.binary_type and source.disabled: + self.disabled_sources.append(source) + elif source.type == self.source_type and not source.disabled: + self.source_code_sources.append(source) + elif source.type == self.source_type and source.disabled: + self.disabled_sources.append(source) + if not source.invalid and source.template in self.source_template.children: + if not source.disabled and source.type == self.binary_type: + self.child_sources.append(source) + elif not source.disabled and source.type == self.source_type: + self.source_code_sources.append(source) + else: + self.disabled_sources.append(source) + self.download_comps = set(comps) + self.cdrom_comps = set(cdrom_comps) + enabled_comps.extend(comps) + enabled_comps.extend(cdrom_comps) + self.enabled_comps = set(enabled_comps) + self.used_media = set(media) + self.get_mirrors() + + def get_mirrors(self, mirror_template=None): + """ + Provide a set of mirrors where you can get the distribution from + """ + # the main server is stored in the template + self.main_server = self.source_template.base_uri + + # other used servers + for medium in self.used_media: + if not medium.startswith("cdrom:"): + # seems to be a network source + self.used_servers.append(medium) + + if len(self.main_sources) == 0: + self.default_server = self.main_server + else: + self.default_server = self.main_sources[0].uri + + # get a list of country codes and real names + self.countries = {} + fname = "/usr/share/xml/iso-codes/iso_3166.xml" + if os.path.exists(fname): + et = ElementTree(file=fname) + # python2.6 compat, the next two lines can get removed + # once we do not use py2.6 anymore + if getattr(et, "iter", None) is None: + et.iter = et.getiterator + it = et.iter("iso_3166_entry") + for elm in it: + try: + descr = elm.attrib["common_name"] + except KeyError: + descr = elm.attrib["name"] + try: + code = elm.attrib["alpha_2_code"] + except KeyError: + code = elm.attrib["alpha_3_code"] + self.countries[code.lower()] = gettext.dgettext("iso_3166", descr) + + # try to guess the nearest mirror from the locale + self.country = None + self.country_code = None + locale = os.getenv("LANG", default="en_UK") + a = locale.find("_") + z = locale.find(".") + if z == -1: + z = len(locale) + country_code = locale[a + 1 : z].lower() + + if mirror_template: + self.nearest_server = mirror_template % country_code + + if country_code in self.countries: + self.country = self.countries[country_code] + self.country_code = country_code + + def _get_mirror_name(self, server): + """Try to get a human readable name for the main mirror of a country + Customize for different distributions""" + country = None + i = server.find("://") + li = server.find(".archive.ubuntu.com") + if i != -1 and li != -1: + country = server[i + len("://") : li] + if country in self.countries: + # TRANSLATORS: %s is a country + return _("Server for %s") % self.countries[country] + else: + return "%s" % server.rstrip("/ ") + + def get_server_list(self): + """Return a list of used and suggested servers""" + + def compare_mirrors(mir1, mir2): + """Helper function that handles comaprision of mirror urls + that could contain trailing slashes""" + return re.match(mir1.strip("/ "), mir2.rstrip("/ ")) + + # Store all available servers: + # Name, URI, active + mirrors = [] + if len(self.used_servers) < 1 or ( + len(self.used_servers) == 1 + and compare_mirrors(self.used_servers[0], self.main_server) + ): + mirrors.append([_("Main server"), self.main_server, True]) + if self.nearest_server: + mirrors.append( + [ + self._get_mirror_name(self.nearest_server), + self.nearest_server, + False, + ] + ) + elif len(self.used_servers) == 1 and not compare_mirrors( + self.used_servers[0], self.main_server + ): + mirrors.append([_("Main server"), self.main_server, False]) + # Only one server is used + server = self.used_servers[0] + + # Append the nearest server if it's not already used + if self.nearest_server: + if not compare_mirrors(server, self.nearest_server): + mirrors.append( + [ + self._get_mirror_name(self.nearest_server), + self.nearest_server, + False, + ] + ) + if server: + mirrors.append([self._get_mirror_name(server), server, True]) + + elif len(self.used_servers) > 1: + # More than one server is used. Since we don't handle this case + # in the user interface we set "custom servers" to true and + # append a list of all used servers + mirrors.append([_("Main server"), self.main_server, False]) + if self.nearest_server: + mirrors.append( + [ + self._get_mirror_name(self.nearest_server), + self.nearest_server, + False, + ] + ) + mirrors.append([_("Custom servers"), None, True]) + for server in self.used_servers: + mirror_entry = [self._get_mirror_name(server), server, False] + if compare_mirrors(server, self.nearest_server) or compare_mirrors( + server, self.main_server + ): + continue + elif mirror_entry not in mirrors: + mirrors.append(mirror_entry) + + return mirrors + + def add_source(self, type=None, uri=None, dist=None, comps=None, comment=""): + """ + Add distribution specific sources + """ + if uri is None: + # FIXME: Add support for the server selector + uri = self.default_server + if dist is None: + dist = self.codename + if comps is None: + comps = list(self.enabled_comps) + if type is None: + type = self.binary_type + + parent = None + file = None + for parent in reversed(self.child_sources) or reversed(self.main_sources): + file = parent.file + break + + new_source = self.sourceslist.add( + type, uri, dist, comps, comment, parent=parent, file=file + ) + # if source code is enabled add a deb-src line after the new + # source + if self.get_source_code and type == self.binary_type: + self.sourceslist.add( + self.source_type, + uri, + dist, + comps, + comment, + file=new_source.file, + parent=new_source, + pos=self.sourceslist.list.index(new_source) + 1, + ) + + def enable_component(self, comp): + """ + Enable a component in all main, child and source code sources + (excluding cdrom based sources) + + comp: the component that should be enabled + """ + comps = list([comp]) + # look for parent components that we may have to add + for source in self.main_sources: + for c in source.template.components: + if c.name == comp and c.parent_component: + if c.parent_component not in comps: + comps.append(c.parent_component) + for c in comps: + self._enable_component(c) + + def _enable_component(self, comp): + def add_component_only_once(source, comps_per_dist): + """ + Check if we already added the component to the repository, since + a repository could be splitted into different apt lines. If not + add the component + """ + # if we don't have that distro, just return (can happen for e.g. + # dapper-update only in deb-src + if source.dist not in comps_per_dist: + return + # if we have seen this component already for this distro, + # return (nothing to do) + if comp in comps_per_dist[source.dist]: + return + # add it + source.comps = source.comps + [comp] + comps_per_dist[source.dist].add(comp) + + sources = [] + sources.extend(self.main_sources) + sources.extend(self.child_sources) + # store what comps are enabled already per distro (where distro is + # e.g. "dapper", "dapper-updates") + comps_per_dist = {} + comps_per_sdist = {} + for s in sources: + if s.type == self.binary_type: + if s.dist not in comps_per_dist: + comps_per_dist[s.dist] = set() + for c in s.comps: + comps_per_dist[s.dist].add(c) + for s in self.source_code_sources: + if s.type == self.source_type: + if s.dist not in comps_per_sdist: + comps_per_sdist[s.dist] = set() + for c in s.comps: + comps_per_sdist[s.dist].add(c) + + # check if there is a main source at all + if len(self.main_sources) < 1: + # create a new main source + self.add_source(comps=["%s" % comp]) + else: + # add the comp to all main, child and source code sources + for source in sources: + add_component_only_once(source, comps_per_dist) + + for source in self.source_code_sources: + add_component_only_once(source, comps_per_sdist) + + # check if there is a main source code source at all + if self.get_source_code: + if len(self.source_code_sources) < 1: + # create a new main source + self.add_source(type=self.source_type, comps=["%s" % comp]) + else: + # add the comp to all main, child and source code sources + for source in self.source_code_sources: + add_component_only_once(source, comps_per_sdist) + + def disable_component(self, comp): + """ + Disable a component in all main, child and source code sources + (excluding cdrom based sources) + """ + sources = [] + sources.extend(self.main_sources) + sources.extend(self.child_sources) + sources.extend(self.source_code_sources) + if comp in self.cdrom_comps: + sources = [] + sources.extend(self.main_sources) + for source in sources: + if comp in source.comps: + comps = source.comps + comps.remove(comp) + source.comps = comps + if len(source.comps) < 1: + self.sourceslist.remove(source) + + def change_server(self, uri): + """Change the server of all distro specific sources to + a given host""" + + def change_server_of_source(source, uri, seen): + # Avoid creating duplicate entries + source.uri = uri + for comp in source.comps: + if [source.uri, source.dist, comp] in seen: + source.comps.remove(comp) + else: + seen.append([source.uri, source.dist, comp]) + if len(source.comps) < 1: + self.sourceslist.remove(source) + + seen_binary = [] + seen_source = [] + self.default_server = uri + for source in self.main_sources: + change_server_of_source(source, uri, seen_binary) + for source in self.child_sources: + # Do not change the forces server of a child source + if ( + source.template.base_uri is None + or source.template.base_uri != source.uri + ): + change_server_of_source(source, uri, seen_binary) + for source in self.source_code_sources: + change_server_of_source(source, uri, seen_source) + + def is_codename(self, name): + """Compare a given name with the release codename.""" + if name == self.codename: + return True + else: + return False + + +class DebianDistribution(Distribution): + """Class to support specific Debian features""" + + def is_codename(self, name): + """Compare a given name with the release codename and check if + if it can be used as a synonym for a development releases""" + if name == self.codename or self.release in ("testing", "unstable"): + return True + else: + return False + + def _get_mirror_name(self, server): + """Try to get a human readable name for the main mirror of a country + Debian specific""" + country = None + i = server.find("://ftp.") + li = server.find(".debian.org") + if i != -1 and li != -1: + country = server[i + len("://ftp.") : li] + if country in self.countries: + # TRANSLATORS: %s is a country + return ( + _("Server for %s") + % gettext.dgettext( + "iso_3166", self.countries[country].rstrip() + ).rstrip() + ) + else: + return "%s" % server.rstrip("/ ") + + def get_mirrors(self): + Distribution.get_mirrors( + self, mirror_template="http://ftp.%s.debian.org/debian/" + ) + + +class UbuntuDistribution(Distribution): + """Class to support specific Ubuntu features""" + + def get_mirrors(self): + Distribution.get_mirrors( + self, mirror_template="http://%s.archive.ubuntu.com/ubuntu/" + ) + + +class UbuntuRTMDistribution(UbuntuDistribution): + """Class to support specific Ubuntu RTM features""" + + def get_mirrors(self): + self.main_server = self.source_template.base_uri + + +def _lsb_release(): + """Call lsb_release --idrc and return a mapping.""" + import errno + from subprocess import PIPE, Popen + + result = { + "Codename": "sid", + "Distributor ID": "Debian", + "Description": "Debian GNU/Linux unstable (sid)", + "Release": "unstable", + } + try: + out = Popen(["lsb_release", "-idrc"], stdout=PIPE).communicate()[0] + # Convert to unicode string, needed for Python 3.1 + out = out.decode("utf-8") + result.update(line.split(":\t") for line in out.split("\n") if ":\t" in line) + except OSError as exc: + if exc.errno != errno.ENOENT: + logging.warning("lsb_release failed, using defaults:" % exc) + return result + + +def _system_image_channel(): + """Get the current channel from system-image-cli -i if possible.""" + import errno + from subprocess import DEVNULL, PIPE, Popen + + try: + out = Popen( + ["system-image-cli", "-i"], + stdout=PIPE, + stderr=DEVNULL, + universal_newlines=True, + ).communicate()[0] + for line in out.splitlines(): + if line.startswith("channel: "): + return line.split(": ", 1)[1] + except OSError as exc: + if exc.errno != errno.ENOENT: + logging.warning("system-image-cli failed, using defaults: %s" % exc) + return None + + +class _OSRelease: + DEFAULT_OS_RELEASE_FILE = "/etc/os-release" + OS_RELEASE_FILE = "/etc/os-release" + + def __init__(self, lsb_compat=True): + self.result = {} + self.valid = False + self.file = _OSRelease.OS_RELEASE_FILE + + if not os.path.isfile(self.file): + return + + self.parse() + self.valid = True + + if lsb_compat: + self.inject_lsb_compat() + + def inject_lsb_compat(self): + self.result["Distributor ID"] = self.result["ID"] + self.result["Description"] = self.result["PRETTY_NAME"] + # Optionals as per os-release spec. + self.result["Codename"] = self.result.get("VERSION_CODENAME") + if not self.result["Codename"]: + # Transient Ubuntu 16.04 field (LP: #1598212) + self.result["Codename"] = self.result.get("UBUNTU_CODENAME") + self.result["Release"] = self.result.get("VERSION_ID") + + def parse(self): + f = open(self.file) + for line in f: + line = line.strip() + if not line: + continue + self.parse_entry(*line.split("=", 1)) + f.close() + + def parse_entry(self, key, value): + value = self.parse_value(value) # Values can be shell strings... + if key == "ID_LIKE" and isinstance(value, str): + # ID_LIKE is specified as quoted space-separated list. This will + # be parsed as string that we need to split manually. + value = value.split(" ") + self.result[key] = value + + def parse_value(self, value): + values = shlex.split(value) + if len(values) == 1: + return values[0] + return values + + +def get_distro(id=None, codename=None, description=None, release=None, is_like=[]): + """ + Check the currently used distribution and return the corresponding + distriubtion class that supports distro specific features. + + If no paramter are given the distro will be auto detected via + a call to lsb-release + """ + # make testing easier + if not (id and codename and description and release): + if id or codename or description or release: + warnings.warn( + "Provided only a subset of arguments", DeprecationWarning, stacklevel=2 + ) + os_release = _OSRelease() + os_result = [] + lsb_result = _lsb_release() + if os_release.valid: + os_result = os_release.result + # TODO: We cannot presently use os-release to fully replace lsb_release + # because os-release's ID, VERSION_ID and VERSION_CODENAME fields + # are specified as lowercase. In lsb_release they can be upcase + # or captizalized. So, switching to os-release would consitute + # a behavior break a which point lsb_release support should be + # fully removed. + # This in particular is a problem for template matching, as this + # matches against Distribution objects and depends on string + # case. + lsb_result = _lsb_release() + id = lsb_result["Distributor ID"] + codename = lsb_result["Codename"] + description = lsb_result["Description"] + release = lsb_result["Release"] + # Not available with LSB, use get directly. + is_like = os_result.get("ID_LIKE", []) + if id == "Ubuntu": + channel = _system_image_channel() + if channel is not None and "ubuntu-rtm/" in channel: + id = "Ubuntu-RTM" + codename = channel.rsplit("/", 1)[1].split("-", 1)[0] + description = codename + release = codename + if id == "Ubuntu": + return UbuntuDistribution(id, codename, description, release, is_like) + if id == "Ubuntu-RTM": + return UbuntuRTMDistribution(id, codename, description, release, is_like) + elif id == "Debian": + return DebianDistribution(id, codename, description, release, is_like) + else: + return Distribution(id, codename, description, release, is_like) diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py new file mode 100644 index 0000000..b227690 --- /dev/null +++ b/aptsources/sourceslist.py @@ -0,0 +1,1083 @@ +# sourceslist.py - Provide an abstraction of the sources.list +# +# Copyright (c) 2004-2023 Canonical Ltd. +# Copyright (c) 2004 Michiel Sikkes +# Copyright (c) 2006-2007 Sebastian Heinlein +# +# Authors: Michiel Sikkes +# Michael Vogt +# Sebastian Heinlein +# +# 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 + +import builtins +import glob +import io +import logging +import os.path +import re +import shutil +import time +import weakref +from collections.abc import Callable, Iterable, Iterator +from typing import Any, Generic, Optional, TypeVar, Union + +import apt_pkg + +from . import _deb822 +from .distinfo import DistInfo, Template + +# from apt_pkg import gettext as _ + +T = TypeVar("T") + +# some global helpers + +__all__ = [ + "is_mirror", + "Deb822SourceEntry", + "SourceEntry", + "NullMatcher", + "SourcesList", + "SourceEntryMatcher", +] + + +def is_mirror(master_uri: str, compare_uri: str) -> bool: + """check if the given add_url is idential or a mirror of orig_uri e.g.: + master_uri = archive.ubuntu.com + compare_uri = de.archive.ubuntu.com + -> True + """ + # remove traling spaces and "/" + compare_uri = compare_uri.rstrip("/ ") + master_uri = master_uri.rstrip("/ ") + # uri is identical + if compare_uri == master_uri: + # print "Identical" + return True + # add uri is a master site and orig_uri has the from "XX.mastersite" + # (e.g. de.archive.ubuntu.com) + try: + compare_srv = compare_uri.split("//")[1] + master_srv = master_uri.split("//")[1] + # print "%s == %s " % (add_srv, orig_srv) + except IndexError: # ok, somethings wrong here + # print "IndexError" + return False + # remove the leading "." (if any) and see if that helps + if "." in compare_srv and compare_srv[compare_srv.index(".") + 1 :] == master_srv: + # print "Mirror" + return True + return False + + +def uniq(s: Iterable[T]) -> list[T]: + """simple and efficient way to return uniq collection + + This is not intended for use with a SourceList. It is provided + for internal use only. It does not have a leading underscore to + not break any old code that uses it; but it should not be used + in new code (and is not listed in __all__).""" + return list(set(s)) + + +class SingleValueProperty(property): + def __init__(self, key: str, doc: str): + self.key = key + self.__doc__ = doc + + def __get__( + self, obj: Optional["Deb822SourceEntry"], objtype: type | None = None + ) -> str | None: + if obj is None: + return self # type: ignore + return obj.section.get(self.key, None) + + def __set__(self, obj: "Deb822SourceEntry", value: str | None) -> None: + if value is None: + del obj.section[self.key] + else: + obj.section[self.key] = value + + +class MultiValueProperty(property): + def __init__(self, key: str, doc: str): + self.key = key + self.__doc__ = doc + + def __get__( + self, obj: Optional["Deb822SourceEntry"], objtype: type | None = None + ) -> list[str]: + if obj is None: + return self # type: ignore + return SourceEntry.mysplit(obj.section.get(self.key, "")) + + def __set__(self, obj: "Deb822SourceEntry", values: list[str]) -> None: + obj.section[self.key] = " ".join(values) + + +class ExplodedEntryProperty(property, Generic[T]): + def __init__(self, parent: T): + self.parent = parent + + def __get__( + self, obj: Optional["ExplodedDeb822SourceEntry"], objtype: type | None = None + ) -> T: + if obj is None: + return self # type: ignore + return self.parent.__get__(obj.parent) # type: ignore + + def __set__(self, obj: "ExplodedDeb822SourceEntry", value: T) -> None: + obj.split_out() + self.parent.__set__(obj.parent, value) # type: ignore + + +def DeprecatedProperty(prop: T) -> T: + return prop + + +def _null_weakref() -> None: + """Behaves like an expired weakref.ref, returning None""" + return None + + +class Deb822SourceEntry: + def __init__( + self, + section: _deb822.Section | str | None, + file: str, + list: Optional["SourcesList"] = None, + ): + if section is None: + self.section = _deb822.Section("") + elif isinstance(section, str): + self.section = _deb822.Section(section) + else: + self.section = section + + self._line = str(self.section) + self.file = file + self.template: Template | None = None # type DistInfo.Suite + self.may_merge = False + self._children = weakref.WeakSet["ExplodedDeb822SourceEntry"]() + + if list: + self._list: Callable[[], SourcesList | None] = weakref.ref(list) + else: + self._list = _null_weakref + + def __eq__(self, other: Any) -> Any: + # FIXME: Implement plurals more correctly + """equal operator for two sources.list entries""" + return ( + self.disabled == other.disabled + and self.type == other.type + and self.uri + and self.uri.rstrip("/") == other.uri.rstrip("/") + and self.dist == other.dist + and self.comps == other.comps + ) + + architectures = MultiValueProperty("Architectures", "The list of architectures") + types = MultiValueProperty("Types", "The list of types") + type = DeprecatedProperty(SingleValueProperty("Types", "The list of types")) + uris = MultiValueProperty("URIs", "URIs in the source") + uri = DeprecatedProperty(SingleValueProperty("URIs", "URIs in the source")) + suites = MultiValueProperty("Suites", "Suites in the source") + dist = DeprecatedProperty(SingleValueProperty("Suites", "Suites in the source")) + comps = MultiValueProperty("Components", "Components in the source") + + @property + def comment(self) -> str: + """Legacy attribute describing the paragraph header.""" + return self.section.header + + @comment.setter + def comment(self, comment: str) -> None: + """Legacy attribute describing the paragraph header.""" + self.section.header = comment + + @property + def trusted(self) -> bool | None: + """Return the value of the Trusted field""" + try: + return apt_pkg.string_to_bool(self.section["Trusted"]) + except KeyError: + return None + + @trusted.setter + def trusted(self, value: bool | None) -> None: + if value is None: + try: + del self.section["Trusted"] + except KeyError: + pass + else: + self.section["Trusted"] = "yes" if value else "no" + + @property + def disabled(self) -> bool: + """Check if Enabled: no is set.""" + return not apt_pkg.string_to_bool(self.section.get("Enabled", "yes")) + + @disabled.setter + def disabled(self, value: bool) -> None: + if value: + self.section["Enabled"] = "no" + else: + try: + del self.section["Enabled"] + except KeyError: + pass + + @property + def invalid(self) -> bool: + """A section is invalid if it doesn't have proper entries.""" + return not self.section + + @property + def line(self) -> str: + """The entire (original) paragraph.""" + return self._line + + def __str__(self) -> str: + return self.str().strip() + + def str(self) -> str: + """Section as a string, newline terminated.""" + return str(self.section) + + def set_enabled(self, enabled: bool) -> None: + """Deprecated (for deb822) accessor for .disabled""" + self.disabled = not enabled + + def merge(self, other: "AnySourceEntry") -> bool: + """Merge the two entries if they are compatible.""" + if ( + not self.may_merge + and self.template is None + and not all(child.template for child in self._children) + ): + return False + if self.file != other.file: + return False + if not isinstance(other, Deb822SourceEntry): + return False + if self.comment != other.comment and not any( + "Added by software-properties" in c for c in (self.comment, other.comment) + ): + return False + + for tag in set(list(self.section.tags) + list(other.section.tags)): + if tag.lower() in ( + "types", + "uris", + "suites", + "components", + "architectures", + "signed-by", + ): + continue + in_self = self.section.get(tag, None) + in_other = other.section.get(tag, None) + if in_self != in_other: + return False + + if ( + sum( + [ + set(self.types) != set(other.types), + set(self.uris) != set(other.uris), + set(self.suites) != set(other.suites), + set(self.comps) != set(other.comps), + set(self.architectures) != set(other.architectures), + ] + ) + > 1 + ): + return False + + for typ in other.types: + if typ not in self.types: + self.types += [typ] + + for uri in other.uris: + if uri not in self.uris: + self.uris += [uri] + + for suite in other.suites: + if suite not in self.suites: + self.suites += [suite] + + for component in other.comps: + if component not in self.comps: + self.comps += [component] + + for arch in other.architectures: + if arch not in self.architectures: + self.architectures += [arch] + + return True + + def _reparent_children(self, to: "Deb822SourceEntry") -> None: + """If we end up being split, check if any of our children need to be reparented to the new parent.""" + for child in self._children: + for typ in to.types: + for uri in to.uris: + for suite in to.suites: + if (child._type, child._uri, child._suite) == (typ, uri, suite): + assert child.parent == self + child._parent = weakref.ref(to) + + +class ExplodedDeb822SourceEntry: + """This represents a bit of a deb822 paragraph corresponding to a legacy sources.list entry""" + + # Mostly we use slots to prevent accidentally assigning unproxied attributes + __slots__ = ["_parent", "_type", "_uri", "_suite", "template", "__weakref__"] + + def __init__(self, parent: Deb822SourceEntry, typ: str, uri: str, suite: str): + self._parent = weakref.ref(parent) + self._type = typ + self._uri = uri + self._suite = suite + self.template = parent.template + parent._children.add(self) + + @property + def parent(self) -> Deb822SourceEntry: + if self._parent is not None: + if (parent := self._parent()) is not None: + return parent + raise ValueError("The parent entry is no longer valid") + + @property + def uri(self) -> str: + self.__check_valid() + return self._uri + + @uri.setter + def uri(self, uri: str) -> None: + self.split_out() + self.parent.uris = [u if u != self._uri else uri for u in self.parent.uris] + self._uri = uri + + @property + def types(self) -> list[str]: + return [self.type] + + @property + def suites(self) -> list[str]: + return [self.dist] + + @property + def uris(self) -> list[str]: + return [self.uri] + + @property + def type(self) -> str: + self.__check_valid() + return self._type + + @type.setter + def type(self, typ: str) -> None: + self.split_out() + self.parent.types = [typ] + self._type = typ + self.__check_valid() + assert self._type == typ + assert self.parent.types == [self._type] + + @property + def dist(self) -> str: + self.__check_valid() + return self._suite + + @dist.setter + def dist(self, suite: str) -> None: + self.split_out() + self.parent.suites = [suite] + self._suite = suite + self.__check_valid() + assert self._suite == suite + assert self.parent.suites == [self._suite] + + def __check_valid(self) -> None: + if self.parent._list() is None: + raise ValueError("The parent entry is dead") + for type in self.parent.types: + for uri in self.parent.uris: + for suite in self.parent.suites: + if (type, uri, suite) == (self._type, self._uri, self._suite): + return + raise ValueError(f"Could not find parent of {self}") + + def split_out(self) -> None: + parent = self.parent + if (parent.types, parent.uris, parent.suites) == ( + [self._type], + [self._uri], + [self._suite], + ): + return + sources_list = parent._list() + if sources_list is None: + raise ValueError("The parent entry is dead") + + try: + index = sources_list.list.index(parent) + except ValueError as e: + raise ValueError( + f"Parent entry for partial deb822 {self} no longer valid" + ) from e + + sources_list.remove(parent) + + reparented = False + for type in reversed(parent.types): + for uri in reversed(parent.uris): + for suite in reversed(parent.suites): + new = Deb822SourceEntry( + section=_deb822.Section(parent.section), + file=parent.file, + list=sources_list, + ) + new.types = [type] + new.uris = [uri] + new.suites = [suite] + new.may_merge = True + + parent._reparent_children(new) + sources_list.list.insert(index, new) + if (type, uri, suite) == (self._type, self._uri, self._suite): + self._parent = weakref.ref(new) + reparented = True + if not reparented: + raise ValueError(f"Could not find parent of {self}") + + def __repr__(self) -> str: + return f" None: + """Set the source to enabled.""" + self.disabled = not enabled + + @property + def file(self) -> str: + """Return the file.""" + return self.parent.file + + +class SourceEntry: + """single sources.list entry""" + + def __init__(self, line: str, file: str | None = None): + self.invalid = False # is the source entry valid + self.disabled = False # is it disabled ('#' in front) + self.type = "" # what type (deb, deb-src) + self.architectures: list[str] = [] # architectures + self.trusted: bool | None = None # Trusted + self.uri = "" # base-uri + self.dist = "" # distribution (dapper, edgy, etc) + self.comps: list[str] = [] # list of available componetns (may empty) + self.comment = "" # (optional) comment + self.line = line # the original sources.list line + if file is None: + file = apt_pkg.config.find_file("Dir::Etc::sourcelist") + if file.endswith(".sources"): + raise ValueError("Classic SourceEntry cannot be written to .sources file") + self.file = file # the file that the entry is located in + self.parse(line) + self.template: Template | None = None # type DistInfo.Suite + self.children: list[SourceEntry] = [] + + def __eq__(self, other: Any) -> Any: + """equal operator for two sources.list entries""" + return ( + self.disabled == other.disabled + and self.type == other.type + and self.uri.rstrip("/") == other.uri.rstrip("/") + and self.dist == other.dist + and self.comps == other.comps + ) + + @staticmethod + def mysplit(line: str) -> list[str]: + """a split() implementation that understands the sources.list + format better and takes [] into account (for e.g. cdroms)""" + line = line.strip() + pieces = [] + tmp = "" + # we are inside a [..] block + p_found = False + space_found = False + for i in range(len(line)): + if line[i] == "[": + if space_found: + space_found = False + p_found = True + pieces.append(tmp) + tmp = line[i] + else: + p_found = True + tmp += line[i] + elif line[i] == "]": + p_found = False + tmp += line[i] + elif space_found and not line[i].isspace(): + # we skip one or more space + space_found = False + pieces.append(tmp) + tmp = line[i] + elif line[i].isspace() and not p_found: + # found a whitespace + space_found = True + else: + tmp += line[i] + # append last piece + if len(tmp) > 0: + pieces.append(tmp) + return pieces + + def parse(self, line: str) -> None: + """parse a given sources.list (textual) line and break it up + into the field we have""" + self.line = line + line = line.strip() + # check if the source is enabled/disabled + if line == "" or line == "#": # empty line + self.invalid = True + return + if line[0] == "#": + self.disabled = True + pieces = line[1:].strip().split() + # if it looks not like a disabled deb line return + if not pieces[0] in ("rpm", "rpm-src", "deb", "deb-src"): + self.invalid = True + return + else: + line = line[1:] + # check for another "#" in the line (this is treated as a comment) + i = line.find("#") + if i > 0: + self.comment = line[i + 1 :] + line = line[:i] + # source is ok, split it and see what we have + pieces = self.mysplit(line) + # Sanity check + if len(pieces) < 3: + self.invalid = True + return + # Type, deb or deb-src + self.type = pieces[0].strip() + # Sanity check + if self.type not in ("deb", "deb-src", "rpm", "rpm-src"): + self.invalid = True + return + + if pieces[1].strip()[0] == "[": + options = pieces.pop(1).strip("[]").split() + for option in options: + try: + key, value = option.split("=", 1) + except Exception: + self.invalid = True + else: + if key == "arch": + self.architectures = value.split(",") + elif key == "trusted": + self.trusted = apt_pkg.string_to_bool(value) + else: + self.invalid = True + + # URI + self.uri = pieces[1].strip() + if len(self.uri) < 1: + self.invalid = True + # distro and components (optional) + # Directory or distro + self.dist = pieces[2].strip() + if len(pieces) > 3: + # List of components + self.comps = pieces[3:] + else: + self.comps = [] + + def set_enabled(self, new_value: bool) -> None: + """set a line to enabled or disabled""" + self.disabled = not new_value + # enable, remove all "#" from the start of the line + if new_value: + self.line = self.line.lstrip().lstrip("#") + else: + # disabled, add a "#" + if self.line.strip()[0] != "#": + self.line = "#" + self.line + + def __str__(self) -> str: + """debug helper""" + return self.str().strip() + + def str(self) -> str: + """return the current line as string""" + if self.invalid: + return self.line + line = "" + if self.disabled: + line = "# " + + line += self.type + + if self.architectures and self.trusted is not None: + line += " [arch={} trusted={}]".format( + ",".join(self.architectures), + "yes" if self.trusted else "no", + ) + elif self.trusted is not None: + line += " [trusted=%s]" % ("yes" if self.trusted else "no") + elif self.architectures: + line += " [arch=%s]" % ",".join(self.architectures) + line += f" {self.uri} {self.dist}" + if len(self.comps) > 0: + line += " " + " ".join(self.comps) + if self.comment != "": + line += " #" + self.comment + line += "\n" + return line + + @property + def types(self) -> list[builtins.str]: + """deb822 compatible accessor for the type""" + return [self.type] + + @property + def uris(self) -> list[builtins.str]: + """deb822 compatible accessor for the uri""" + return [self.uri] + + @property + def suites(self) -> list[builtins.str]: + """deb822 compatible accessor for the suite""" + return [self.dist] + + +AnySourceEntry = Union[SourceEntry, Deb822SourceEntry] +AnyExplodedSourceEntry = Union[ + SourceEntry, Deb822SourceEntry, ExplodedDeb822SourceEntry +] + + +class NullMatcher: + """a Matcher that does nothing""" + + def match(self, s: AnyExplodedSourceEntry) -> bool: + return True + + +class SourcesList: + """represents the full sources.list + sources.list.d file""" + + def __init__( + self, + withMatcher: bool = True, + matcherPath: str = "/usr/share/python-apt/templates/", + *, + deb822: bool = False, + ): + self.list: list[AnySourceEntry] = [] # the actual SourceEntries Type + self.matcher: NullMatcher | SourceEntryMatcher + if withMatcher: + self.matcher = SourceEntryMatcher(matcherPath) + else: + self.matcher = NullMatcher() + self.deb822 = deb822 + self.refresh() + + def refresh(self) -> None: + """update the list of known entries""" + self.list = [] + # read sources.list + file = apt_pkg.config.find_file("Dir::Etc::sourcelist") + if file != "/dev/null" and os.path.exists(file): + self.load(file) + # read sources.list.d + partsdir = apt_pkg.config.find_dir("Dir::Etc::sourceparts") + if partsdir != "/dev/null" and os.path.exists(partsdir): + for file in os.listdir(partsdir): + if (self.deb822 and file.endswith(".sources")) or file.endswith( + ".list" + ): + self.load(os.path.join(partsdir, file)) + # check if the source item fits a predefined template + for source in self.list: + if not source.invalid: + self.matcher.match(source) + + def __iter__(self) -> Iterator[AnySourceEntry]: + """simple iterator to go over self.list, returns SourceEntry + types""" + yield from self.list + + def __find( + self, *predicates: Callable[[AnyExplodedSourceEntry], bool], **attrs: Any + ) -> Iterator[AnyExplodedSourceEntry]: + uri = attrs.pop("uri", None) + for source in self.exploded_list(): + if uri and source.uri and uri.rstrip("/") != source.uri.rstrip("/"): + continue + if all(getattr(source, key) == attrs[key] for key in attrs) and all( + predicate(source) for predicate in predicates + ): + yield source + + def add( + self, + type: str, + uri: str, + dist: str, + orig_comps: list[str], + comment: str = "", + pos: int = -1, + file: str | None = None, + architectures: Iterable[str] = [], + parent: AnyExplodedSourceEntry | None = None, + ) -> AnyExplodedSourceEntry: + """ + Add a new source to the sources.list. + The method will search for existing matching repos and will try to + reuse them as far as possible + """ + + type = type.strip() + disabled = type.startswith("#") + if disabled: + type = type[1:].lstrip() + architectures = set(architectures) + # create a working copy of the component list so that + # we can modify it later + comps = orig_comps[:] + sources = self.__find( + lambda s: set(s.architectures) == architectures, + disabled=disabled, + invalid=False, + type=type, + uri=uri, + dist=dist, + ) + # check if we have this source already in the sources.list + for source in sources: + for new_comp in comps: + if new_comp in source.comps: + # we have this component already, delete it + # from the new_comps list + del comps[comps.index(new_comp)] + if len(comps) == 0: + return source + + sources = self.__find( + lambda s: set(s.architectures) == architectures, + invalid=False, + type=type, + uri=uri, + dist=dist, + ) + for source in sources: + if source.disabled == disabled: + # if there is a repo with the same (disabled, type, uri, dist) + # just add the components + if set(source.comps) != set(comps): + source.comps = uniq(source.comps + comps) + return source + elif source.disabled and not disabled: + # enable any matching (type, uri, dist), but disabled repo + if set(source.comps) == set(comps): + source.disabled = False + return source + + new_entry: AnySourceEntry + if file is None: + file = apt_pkg.config.find_file("Dir::Etc::sourcelist") + if file.endswith(".sources"): + new_entry = Deb822SourceEntry(None, file=file, list=self) + if parent: + parent = getattr(parent, "parent", parent) + assert isinstance(parent, Deb822SourceEntry) + for k in parent.section.tags: + new_entry.section[k] = parent.section[k] + new_entry.types = [type] + new_entry.uris = [uri] + new_entry.suites = [dist] + new_entry.comps = comps + if architectures: + new_entry.architectures = list(architectures) + new_entry.section.header = comment + new_entry.disabled = disabled + else: + # there isn't any matching source, so create a new line and parse it + parts = [ + "#" if disabled else "", + type, + ("[arch=%s]" % ",".join(architectures)) if architectures else "", + uri, + dist, + ] + parts.extend(comps) + if comment: + parts.append("#" + comment) + line = " ".join(part for part in parts if part) + "\n" + + new_entry = SourceEntry(line) + if file is not None: + new_entry.file = file + + self.matcher.match(new_entry) + if pos < 0: + self.list.append(new_entry) + else: + self.list.insert(pos, new_entry) + return new_entry + + def remove(self, source_entry: AnyExplodedSourceEntry) -> None: + """remove the specified entry from the sources.list""" + if isinstance(source_entry, ExplodedDeb822SourceEntry): + source_entry.split_out() + source_entry = source_entry.parent + self.list.remove(source_entry) + + def restore_backup(self, backup_ext: str) -> None: + "restore sources.list files based on the backup extension" + file = apt_pkg.config.find_file("Dir::Etc::sourcelist") + if os.path.exists(file + backup_ext) and os.path.exists(file): + shutil.copy(file + backup_ext, file) + # now sources.list.d + partsdir = apt_pkg.config.find_dir("Dir::Etc::sourceparts") + for file in glob.glob("%s/*" % partsdir): + if os.path.exists(file + backup_ext): + shutil.copy(file + backup_ext, file) + + def backup(self, backup_ext: str | None = None) -> str: + """make a backup of the current source files, if no backup extension + is given, the current date/time is used (and returned)""" + already_backuped: Iterable[str] = set() + if backup_ext is None: + backup_ext = time.strftime("%y%m%d.%H%M") + for source in self.list: + if source.file not in already_backuped and os.path.exists(source.file): + shutil.copy(source.file, f"{source.file}{backup_ext}") + return backup_ext + + def load(self, file: str) -> None: + """(re)load the current sources""" + try: + with open(file) as f: + if file.endswith(".sources"): + for section in _deb822.File(f): + self.list.append(Deb822SourceEntry(section, file, list=self)) + else: + for line in f: + source = SourceEntry(line, file) + self.list.append(source) + except Exception as exc: + logging.warning(f"could not open file '{file}': {exc}\n") + + def index(self, entry: AnyExplodedSourceEntry) -> int: + if isinstance(entry, ExplodedDeb822SourceEntry): + return self.list.index(entry.parent) + return self.list.index(entry) + + def merge(self) -> None: + """Merge consecutive entries that have been split back together.""" + merged = True + while merged: + i = 0 + merged = False + while i + 1 < len(self.list): + entry = self.list[i] + if isinstance(entry, Deb822SourceEntry): + j = i + 1 + while j < len(self.list): + if entry.merge(self.list[j]): + del self.list[j] + merged = True + else: + j += 1 + i += 1 + + def save(self) -> None: + """save the current sources""" + files: dict[str, io.TextIOWrapper] = {} + # write an empty default config file if there aren't any sources + if len(self.list) == 0: + path = apt_pkg.config.find_file("Dir::Etc::sourcelist") + header = ( + "## See sources.list(5) for more information, especialy\n" + "# Remember that you can only use http, ftp or file URIs\n" + "# CDROMs are managed through the apt-cdrom tool.\n" + ) + + with open(path, "w") as f: + f.write(header) + return + + self.merge() + try: + for source in self.list: + if source.file not in files: + files[source.file] = open(source.file, "w") + elif isinstance(source, Deb822SourceEntry): + files[source.file].write("\n") + files[source.file].write(source.str()) + finally: + for f in files.values(): + f.close() + + def check_for_relations( + self, sources_list: Iterable[AnySourceEntry] + ) -> tuple[list[AnySourceEntry], dict[Template, list[AnySourceEntry]]]: + """get all parent and child channels in the sources list""" + parents = [] + used_child_templates: dict[Template, list[AnySourceEntry]] = {} + for source in sources_list: + # try to avoid checking uninterressting sources + if source.template is None: + continue + # set up a dict with all used child templates and corresponding + # source entries + if source.template.child: + key = source.template + if key not in used_child_templates: + used_child_templates[key] = [] + temp = used_child_templates[key] + temp.append(source) + else: + # store each source with children aka. a parent :) + if len(source.template.children) > 0: + parents.append(source) + # print self.used_child_templates + # print self.parents + return (parents, used_child_templates) + + def exploded_list(self) -> list[AnyExplodedSourceEntry]: + """Present an exploded view of the list where each entry corresponds exactly to a Release file. + + A release file is uniquely identified by the triplet (type, uri, suite). Old style entries + always referred to a single release file, but deb822 entries allow multiple values for each + of those fields. + """ + res: list[AnyExplodedSourceEntry] = [] + for entry in self.list: + if isinstance(entry, SourceEntry): + res.append(entry) + elif ( + len(entry.types) == 1 + and len(entry.uris) == 1 + and len(entry.suites) == 1 + ): + res.append(entry) + else: + for typ in entry.types: + for uri in entry.uris: + for sui in entry.suites: + res.append(ExplodedDeb822SourceEntry(entry, typ, uri, sui)) + self.matcher.match(res[-1]) + + return res + + +class SourceEntryMatcher: + """matcher class to make a source entry look nice + lots of predefined matchers to make it i18n/gettext friendly + """ + + def __init__(self, matcherPath: str): + self.templates: list[Template] = [] + # Get the human readable channel and comp names from the channel .infos + spec_files = glob.glob("%s/*.info" % matcherPath) + for f in spec_files: + f = os.path.basename(f) + i = f.find(".info") + f = f[0:i] + dist = DistInfo(f, base_dir=matcherPath) + for template in dist.templates: + if template.match_uri is not None: + self.templates.append(template) + return + + def match(self, source: AnyExplodedSourceEntry) -> bool: + """Add a matching template to the source""" + found = False + for template in self.templates: + if source.uri is None or source.dist is None: + continue + if ( + template.match_uri is not None + and template.match_name is not None + and source.uri is not None + and source.dist is not None + and re.search(template.match_uri, source.uri) + and re.match(template.match_name, source.dist) + and + # deb is a valid fallback for deb-src (if that is not + # definied, see #760035 + (source.type == template.type or template.type == "deb") + ): + found = True + source.template = template + break + elif ( + template.is_mirror(source.uri) + and template.match_name is not None + and source.dist is not None + and re.match(template.match_name, source.dist) + ): + found = True + source.template = template + break + return found + + +# some simple tests +if __name__ == "__main__": + apt_pkg.init_config() + sources = SourcesList() + + for entry in sources: + logging.info("entry %s" % entry.str()) + # print entry.uri + + mirror = is_mirror( + "http://archive.ubuntu.com/ubuntu/", "http://de.archive.ubuntu.com/ubuntu/" + ) + logging.info("is_mirror(): %s" % mirror) + + logging.info( + is_mirror( + "http://archive.ubuntu.com/ubuntu", "http://de.archive.ubuntu.com/ubuntu/" + ) + ) + logging.info( + is_mirror( + "http://archive.ubuntu.com/ubuntu/", "http://de.archive.ubuntu.com/ubuntu" + ) + ) diff --git a/data/templates/Blankon.info.in b/data/templates/Blankon.info.in new file mode 100644 index 0000000..f27c65b --- /dev/null +++ b/data/templates/Blankon.info.in @@ -0,0 +1,370 @@ +ChangelogURI: http://arsip.blankonlinux.or.id/blankon/changelogs/pool/%s/%s/%s/%s_%s/changelog + +Suite: tambora +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon/ +MatchURI: arsip.blankonlinux.or.id/blankon +MirrorsFile-amd64: Blankon.mirrors +MirrorsFile-i386: Blankon.mirrors +_Description: Blankon 10.0 'Tambora' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: Blankon-supported Free/Open Source software +Component: extras +_CompDescription: Community-maintained +_CompDescriptionLong: Community-maintained Free/Open Source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices +Component: extras-restricted +_CompDescription: Restricted software +_CompDescriptionLong: Software restricted by copyright or legal issues + +Suite: tambora +MatchName: .* +BaseURI: cdrom:\[Blankon.*10.0 +MatchURI: cdrom:\[Blankon.*10.0 +_Description: CDROM with Blankon 10.0 'Tambora' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: tambora-security +ParentSuite: tambora +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon/ +MatchURI: arsip.blankonlinux.or.id/blankon +_Description: Important security updates + +Suite: tambora-updates +ParentSuite: tambora +RepositoryType: deb +_Description: Recommended updates + +Suite: suroboyo +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon/ +MatchURI: arsip.blankonlinux.or.id/blankon +MirrorsFile-amd64: Blankon.mirrors +MirrorsFile-i386: Blankon.mirrors +_Description: Blankon 9.0 'Suroboyo' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: Blankon-supported Free/Open Source software +Component: extras +_CompDescription: Community-maintained +_CompDescriptionLong: Community-maintained Free/Open Source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices +Component: extras-restricted +_CompDescription: Restricted software +_CompDescriptionLong: Software restricted by copyright or legal issues + +Suite: suroboyo +MatchName: .* +BaseURI: cdrom:\[Blankon.*9.0 +MatchURI: cdrom:\[Blankon.*9.0 +_Description: CDROM with Blankon 9.0 'Suroboyo' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: suroboyo-security +ParentSuite: suroboyo +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon/ +MatchURI: arsip.blankonlinux.or.id/blankon +_Description: Important security updates + +Suite: suroboyo-updates +ParentSuite: suroboyo +RepositoryType: deb +_Description: Recommended updates + +Suite: rote +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon/ +MatchURI: arsip.blankonlinux.or.id/blankon +MirrorsFile-amd64: Blankon.mirrors +MirrorsFile-i386: Blankon.mirrors +_Description: Blankon 8.0 'Rote' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: Blankon-supported Free/Open Source software +Component: extras +_CompDescription: Community-maintained +_CompDescriptionLong: Community-maintained Free/Open Source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices +Component: extras-restricted +_CompDescription: Restricted software +_CompDescriptionLong: Software restricted by copyright or legal issues + +Suite: rote +MatchName: .* +BaseURI: cdrom:\[Blankon.*8.0 +MatchURI: cdrom:\[Blankon.*8.0 +_Description: CDROM with Blankon 8.0 'Rote' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: rote-security +ParentSuite: rote +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon/ +MatchURI: arsip.blankonlinux.or.id/blankon +_Description: Important security updates + +Suite: rote-updates +ParentSuite: rote +RepositoryType: deb +_Description: Recommended updates + +Suite: pattimura +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon-legacy/ +MatchURI: arsip.blankonlinux.or.id/blankon-legacy +MirrorsFile-amd64: Blankon.mirrors +MirrorsFile-i386: Blankon.mirrors +_Description: Blankon 7.0 'Pattimura' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: Blankon-supported Free/Open Source software +Component: extras +_CompDescription: Community-maintained +_CompDescriptionLong: Community-maintained Free/Open Source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices +Component: extras-restricted +_CompDescription: Restricted software +_CompDescriptionLong: Software restricted by copyright or legal issues + +Suite: pattimura +MatchName: .* +BaseURI: cdrom:\[Blankon.*7.0 +MatchURI: cdrom:\[Blankon.*7.0 +_Description: CDROM with Blankon 7.0 'Pattimura' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: pattimura-security +ParentSuite: pattimura +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon-legacy/ +MatchURI: arsip.blankonlinux.or.id/blankon-legacy +_Description: Important security updates + +Suite: pattimura-updates +ParentSuite: pattimura +RepositoryType: deb +_Description: Recommended updates + +Suite: ombilin +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon-legacy/ +MatchURI: arsip.blankonlinux.or.id/blankon-legacy +MirrorsFile-amd64: Blankon.mirrors +MirrorsFile-i386: Blankon.mirrors +_Description: Blankon 6.0 'Ombilin' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: Blankon-supported Free/Open Source software +Component: extras +_CompDescription: Community-maintained +_CompDescriptionLong: Community-maintained Free/Open Source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices +Component: extras-restricted +_CompDescription: Restricted software +_CompDescriptionLong: Software restricted by copyright or legal issues + +Suite: ombilin +MatchName: .* +BaseURI: cdrom:\[Blankon.*6.0 +MatchURI: cdrom:\[Blankon.*6.0 +_Description: CDROM with Blankon 6.0 'Ombilin' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: ombilin-security +ParentSuite: ombilin +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon-legacy/ +MatchURI: arsip.blankonlinux.or.id/blankon-legacy +_Description: Important security updates + +Suite: ombilin-updates +ParentSuite: ombilin +RepositoryType: deb +_Description: Recommended updates + +Suite: nanggar +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon-legacy/ +MatchURI: arsip.blankonlinux.or.id/blankon-legacy +MirrorsFile-amd64: Blankon.mirrors +MirrorsFile-i386: Blankon.mirrors +_Description: Blankon 5.0 'Nanggar' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: BlankOn-supported Open Source software +Component: universe +_CompDescription: Community-maintained +_CompDescriptionLong: Community-maintained Open Source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices +Component: multiverse +_CompDescription: Restricted software +_CompDescriptionLong: Software restricted by copyright or legal issues + +Suite: nanggar +MatchName: .* +BaseURI: cdrom:\[Blankon.*5.0 +MatchURI: cdrom:\[Blankon.*5.0 +_Description: Cdrom with Blankon 5.0 'Nanggar' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: nanggar-security +ParentSuite: nanggar +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon-legacy/ +MatchURI: arsip.blankonlinux.or.id/blankon-legacy +_Description: Important security updates + +Suite: nanggar-updates +ParentSuite: nanggar +RepositoryType: deb +_Description: Recommended updates + +Suite: meuligoe +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon-legacy/ +MatchURI: arsip.blankonlinux.or.id/blankon-legacy +MirrorsFile-amd64: Blankon.mirrors +MirrorsFile-i386: Blankon.mirrors +_Description: Blankon 4.1 'Meuligoe' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: BlankOn-supported Open Source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices + +Suite: meuligoe +MatchName: .* +BaseURI: cdrom:\[Blankon.*4.1 +MatchURI: cdrom:\[Blankon.*4.1 +_Description: Cdrom with Blankon 4.1 'Meuligoe' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: meuligoe-security +ParentSuite: meuligoe +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon-legacy/ +MatchURI: arsip.blankonlinux.or.id/blankon-legacy +_Description: Important security updates + +Suite: meuligoe-updates +ParentSuite: meuligoe +RepositoryType: deb +_Description: Recommended updates + +Suite: lontara +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon-legacy/ +MatchURI: arsip.blankonlinux.or.id/blankon-legacy +MirrorsFile-amd64: Blankon.mirrors +MirrorsFile-i386: Blankon.mirrors +_Description: BlankOn 3.0 'Lontara' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: BlankOn-supported Open Source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices + +Suite: lontara +MatchName: .* +BaseURI: cdrom:\[Blankon.*3.0 +MatchURI: cdrom:\[Blankon.*3.0 +_Description: Cdrom with Blankon 3.0 'Lontara' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: lontara-security +ParentSuite: lontara +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon-legacy/ +MatchURI: arsip.blankonlinux.or.id/blankon-legacy +_Description: Important security updates + +Suite: lontara-updates +ParentSuite: lontara +RepositoryType: deb +_Description: Recommended updates + +Suite: konde +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon-legacy/ +MatchURI: arsip.blankonlinux.or.id/blankon-legacy +MirrorsFile-amd64: Blankon.mirrors +MirrorsFile-i386: Blankon.mirrors +_Description: Blankon 2.0 'Konde' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: BlankOn-supported Open Source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices + +Suite: konde +MatchName: .* +BaseURI: cdrom:\[Blankon.*2.0 +MatchURI: cdrom:\[Blankon.*2.0 +_Description: Cdrom with Blankon 2.0 'Konde' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: konde-security +ParentSuite: konde +RepositoryType: deb +BaseURI: http://arsip.blankonlinux.or.id/blankon-legacy/ +MatchURI: arsip.blankonlinux.or.id/blankon-legacy +_Description: Important security updates + +Suite: konde-updates +ParentSuite: konde +RepositoryType: deb +_Description: Recommended updates diff --git a/data/templates/Blankon.mirrors b/data/templates/Blankon.mirrors new file mode 100644 index 0000000..f277c03 --- /dev/null +++ b/data/templates/Blankon.mirrors @@ -0,0 +1,17 @@ +#LOC:ID +http://kambing.ui.ac.id/blankon/ +http://mirror.omadata.com/blankon/ +http://repo.ugm.ac.id/repo/blankon/ +http://buaya.klas.or.id/blankon/ +http://bos.fkip.uns.ac.id/blankon +http://pandawa.ipb.ac.id/blankon/ +http://dl2.foss-id.web.id/blankon/ +http://shol.vlsm.org/blankon/ +http://openstorage.gunadarma.ac.id/blankon/ +http://debian.rab.co.id/blankon/ +http://singo.ub.ac.id/blankon/ +http://ftp.paudni.kemdiknas.go.id/blankon/ +http://blankon.idrepo.or.id/blankon/ +http://mirror.kioss.undip.ac.id/blankon/ +http://repo.unnes.ac.id/repo/blankon/ +http://kartolo.sby.datautama.net.id/blankon/ diff --git a/data/templates/Debian.info.in b/data/templates/Debian.info.in new file mode 100644 index 0000000..bc86a5e --- /dev/null +++ b/data/templates/Debian.info.in @@ -0,0 +1,119 @@ +_ChangelogURI: https://metadata.ftp-master.debian.org/changelogs/%s/%s/%s/%s_%s_changelog +X-Exclude-Suites: buzz, rex, bo, hamm, slink, potato, woody, experimental + +Suite: {series} +RepositoryType: deb +BaseURI: https://deb.debian.org/debian/ +MatchURI: ((http|https|ftp)[0-9]*\.([a-z]*\.){{0,1}}|deb\.|httpredir\.)debian\.org +MirrorsFile: Debian.mirrors +_Description: Debian {version} '{codename}' +Component: main +_CompDescription: Officially supported +Component: contrib +_CompDescription: DFSG-compatible Software with Non-Free Dependencies +Component: non-free-firmware +_CompDescription: Non-DFSG-compatible Firmware for Hardware Support +Component: non-free +_CompDescription: Non-DFSG-compatible Software +X-Version: ge 12 + +Suite: {series} +RepositoryType: deb +BaseURI: https://deb.debian.org/debian/ +MatchURI: ((http|https|ftp)[0-9]*\.([a-z]*\.){{0,1}}|deb\.|httpredir\.)debian\.org +MirrorsFile: Debian.mirrors +_Description: Debian {version} '{codename}' +Component: main +_CompDescription: Officially supported +Component: contrib +_CompDescription: DFSG-compatible Software with Non-Free Dependencies +Component: non-free +_CompDescription: Non-DFSG-compatible Software +X-Version: le 11 + +Suite: {series}-security +RepositoryType: deb +BaseURI: https://security.debian.org/ +MatchURI: security\.debian\.org +ParentSuite: {series} +_Description: Security updates +X-Version: ge 11 + +Suite: {series}/updates +RepositoryType: deb +BaseURI: https://security.debian.org/ +MatchURI: security\.debian\.org +ParentSuite: {series} +_Description: Security updates +X-Version: le 10 + +Suite: {series}-updates +RepositoryType: deb +ParentSuite: {series} +_Description: Recommended updates +X-Version: ge 7 + +Suite: {series}-proposed-updates +RepositoryType: deb +ParentSuite: {series} +_Description: Proposed updates + +Suite: stable +RepositoryType: deb +BaseURI: https://deb.debian.org/debian/ +MatchURI: ((http|https|ftp)[0-9]*\.([a-z]*\.){0,1}|deb\.|httpredir\.)debian\.org +MirrorsFile: Debian.mirrors +_Description: Debian current stable release +Component: main +_CompDescription: Officially supported +Component: contrib +_CompDescription: DFSG-compatible Software with Non-Free Dependencies +Component: non-free-firmware +_CompDescription: Non-DFSG-compatible Firmware for Hardware Support +Component: non-free +_CompDescription: Non-DFSG-compatible Software + +Suite: testing +RepositoryType: deb +BaseURI: https://deb.debian.org/debian/ +MatchURI: ((http|https|ftp)[0-9]*\.([a-z]*\.){0,1}|deb\.|httpredir\.)debian\.org +MirrorsFile: Debian.mirrors +_Description: Debian testing +Component: main +_CompDescription: Officially supported +Component: contrib +_CompDescription: DFSG-compatible Software with Non-Free Dependencies +Component: non-free-firmware +_CompDescription: Non-DFSG-compatible Firmware for Hardware Support +Component: non-free +_CompDescription: Non-DFSG-compatible Software + +Suite: sid +RepositoryType: deb +BaseURI: https://deb.debian.org/debian/ +MatchURI: ((http|https|ftp)[0-9]*\.([a-z]*\.){0,1}|deb\.|httpredir\.)debian\.org +MirrorsFile: Debian.mirrors +_Description: Debian 'Sid' (unstable) +Component: main +_CompDescription: Officially supported +Component: contrib +_CompDescription: DFSG-compatible Software with Non-Free Dependencies +Component: non-free-firmware +_CompDescription: Non-DFSG-compatible Firmware for Hardware Support +Component: non-free +_CompDescription: Non-DFSG-compatible Software + +Suite: unstable +RepositoryType: deb +BaseURI: https://deb.debian.org/debian/ +MatchURI: ((http|https|ftp)[0-9]*\.([a-z]*\.){0,1}|deb\.|httpredir\.)debian\.org +MirrorsFile: Debian.mirrors +_Description: Debian 'Sid' (unstable) +Component: main +_CompDescription: Officially supported +Component: contrib +_CompDescription: DFSG-compatible Software with Non-Free Dependencies +Component: non-free-firmware +_CompDescription: Non-DFSG-compatible Firmware for Hardware Support +Component: non-free +_CompDescription: Non-DFSG-compatible Software diff --git a/data/templates/Debian.mirrors b/data/templates/Debian.mirrors new file mode 100644 index 0000000..fdb09f1 --- /dev/null +++ b/data/templates/Debian.mirrors @@ -0,0 +1,394 @@ +#LOC:AM +http://ftp.am.debian.org/debian/ +http://mirrors.asnet.am/debian/ +#LOC:AR +http://debian.unnoba.edu.ar/debian/ +#LOC:AT +http://debian.anexia.at/debian/ +http://debian.lagis.at/debian/ +http://debian.mur.at/debian/ +http://debian.sil.at/debian/ +http://ftp.at.debian.org/debian/ +http://ftp.tu-graz.ac.at/mirror/debian/ +http://mirror.alwyzon.net/debian/ +#LOC:AU +http://debian.mirror.digitalpacific.com.au/debian/ +http://ftp.au.debian.org/debian/ +http://mirror.aarnet.edu.au/debian/ +http://mirror.amaze.com.au/debian/ +http://mirror.gsl.icu/debian/ +http://mirror.linux.org.au/debian/ +http://mirror.overthewire.com.au/debian/ +http://mirror.realcompute.io/debian/ +http://mirrors.xtom.au/debian/ +#LOC:BE +http://ftp.be.debian.org/debian/ +http://ftp.belnet.be/debian/ +http://mirror.as35701.net/debian/ +#LOC:BG +http://debian.a1.bg/debian/ +http://debian.ludost.net/debian/ +http://debian.mnet.bg/debian/ +http://debian.telecoms.bg/debian/ +http://ftp.bg.debian.org/debian/ +http://ftp.uni-sofia.bg/debian/ +http://mirror.telepoint.bg/debian/ +http://mirrors.netix.net/debian/ +#LOC:BR +http://alcateia.ufscar.br/debian/ +http://debian.c3sl.ufpr.br/debian/ +http://ftp.br.debian.org/debian/ +http://mirror.uepg.br/debian/ +#LOC:BY +http://ftp.by.debian.org/debian/ +http://ftp.byfly.by/debian/ +http://mirror.datacenter.by/debian/ +#LOC:CA +http://debian.mirror.iweb.ca/debian/ +http://mirror.csclub.uwaterloo.ca/debian/ +http://mirror.dst.ca/debian/ +http://mirror.estone.ca/debian/ +http://mirror.it.ubc.ca/debian/ +http://mirror01-pcl-ott1.accuris.ca/debian/ +#LOC:CH +http://debian.ethz.ch/debian/ +http://ftp.ch.debian.org/debian/ +http://mirror.init7.net/debian/ +http://mirror.iway.ch/debian/ +http://mirror.sinavps.ch/debian/ +http://mirror1.infomaniak.com/debian/ +http://mirror2.infomaniak.com/debian/ +http://pkg.adfinis.com/debian/ +#LOC:CL +http://debian.redlibre.cl/debian/ +http://ftp.cl.debian.org/debian/ +http://mirror.hnd.cl/debian/ +http://mirror.insacom.cl/debian/ +http://mirror.ufro.cl/debian/ +#LOC:CN +http://ftp.cn.debian.org/debian/ +http://mirror.nju.edu.cn/debian/ +http://mirror.nyist.edu.cn/debian/ +http://mirror.sjtu.edu.cn/debian/ +http://mirrors.163.com/debian/ +http://mirrors.bfsu.edu.cn/debian/ +http://mirrors.huaweicloud.com/debian/ +http://mirrors.jlu.edu.cn/debian/ +http://mirrors.neusoft.edu.cn/debian/ +http://mirrors.tuna.tsinghua.edu.cn/debian/ +http://mirrors.ustc.edu.cn/debian/ +http://mirrors.zju.edu.cn/debian/ +#LOC:CR +http://debianmirror.una.ac.cr/debian/ +#LOC:CZ +http://debian.mirror.web4u.cz/ +http://debian.superhosting.cz/debian/ +http://ftp.cvut.cz/debian/ +http://ftp.cz.debian.org/debian/ +http://ftp.debian.cz/debian/ +http://ftp.sh.cvut.cz/debian/ +http://ftp.zcu.cz/debian/ +http://merlin.fit.vutbr.cz/debian/ +http://mirror-prg.webglobe.com/debian/ +http://mirror.dkm.cz/debian/ +http://mirror.it4i.cz/debian/ +http://mirrors.nic.cz/debian/ +#LOC:DE +http://artfiles.org/debian/ +http://de.mirrors.clouvider.net/debian/ +http://debian.charite.de/debian/ +http://debian.inf.tu-dresden.de/debian/ +http://debian.intergenia.de/debian/ +http://debian.mirror.iphh.net/debian/ +http://debian.mirror.lrz.de/debian/ +http://debian.netcologne.de/debian/ +http://debian.tu-bs.de/debian/ +http://ftp-stud.hs-esslingen.de/debian/ +http://ftp.de.debian.org/debian/ +http://ftp.fau.de/debian/ +http://ftp.gwdg.de/debian/ +http://ftp.hosteurope.de/mirror/ftp.debian.org/debian/ +http://ftp.plusline.net/debian/ +http://ftp.tu-chemnitz.de/debian/ +http://ftp.tu-clausthal.de/debian/ +http://ftp.uni-bayreuth.de/debian/ +http://ftp.uni-hannover.de/debian/debian/ +http://ftp.uni-kl.de/debian/ +http://ftp.uni-mainz.de/debian/ +http://ftp.wrz.de/debian/ +http://mirror.23m.com/debian/ +http://mirror.de.leaseweb.net/debian/ +http://mirror.dogado.de/debian/ +http://mirror.eu.oneandone.net/debian/ +http://mirror.informatik.tu-freiberg.de/debian/ +http://mirror.ipb.de/debian/ +http://mirror.netzwerge.de/debian/ +http://mirror.united-gameserver.de/debian/ +http://mirror.wtnet.de/debian/ +http://mirrors.xtom.de/debian/ +http://packages.hs-regensburg.de/debian/ +http://pubmirror.plutex.de/debian/ +#LOC:DK +http://ftp.dk.debian.org/debian/ +http://mirror.asergo.com/debian/ +http://mirror.one.com/debian/ +http://mirrors.dotsrc.org/debian/ +http://mirrors.rackhosting.com/debian/ +#LOC:EE +http://mirrors.xtom.ee/debian/ +#LOC:ES +http://debian.grn.cat/debian/ +http://debian.redimadrid.es/debian/ +http://debian.redparra.com/debian/ +http://debian.uvigo.es/debian/ +http://ftp.caliu.cat/debian/ +http://ftp.cica.es/debian/ +http://ftp.es.debian.org/debian/ +http://ftp.udc.es/debian/ +http://repo.ifca.es/debian/ +http://softlibre.unizar.es/debian/ +http://ulises.hostalia.com/debian/ +#LOC:FI +http://ftp.fi.debian.org/debian/ +http://www.nic.funet.fi/debian/ +#LOC:FR +http://deb-mir1.naitways.net/debian/ +http://debian.apt-mirror.de/debian/ +http://debian.obspm.fr/debian/ +http://debian.polytech-lille.fr/debian/ +http://debian.proxad.net/debian/ +http://debian.univ-tlse2.fr/debian/ +http://ftp.ec-m.fr/debian/ +http://ftp.fr.debian.org/debian/ +http://ftp.lip6.fr/pub/linux/distributions/debian/ +http://ftp.rezopole.net/debian/ +http://ftp.u-picardie.fr/debian/ +http://ftp.u-strasbg.fr/debian/ +http://ftp.univ-pau.fr/linux/mirrors/debian/ +http://miroir.univ-lorraine.fr/debian/ +http://mirror.gitoyen.net/debian/ +http://mirror.ibcp.fr/debian/ +http://mirror.johnnybegood.fr/debian/ +http://mirror.plusserver.com/debian/debian/ +http://mirrors.ircam.fr/pub/debian/ +#LOC:GB +http://debian.mirror.uk.sargasso.net/debian/ +http://debian.mirrors.uk2.net/debian/ +http://free.hands.com/debian/ +http://ftp.ticklers.org/debian/ +http://ftp.uk.debian.org/debian/ +http://mirror.cov.ukservers.com/debian/ +http://mirror.lchost.net/debian/ +http://mirror.mythic-beasts.com/debian/ +http://mirror.ox.ac.uk/debian/ +http://mirror.positive-internet.com/debian/ +http://mirror.sov.uk.goscomb.net/debian/ +http://mirror.vinehost.net/debian/ +http://mirrors.coreix.net/debian/ +http://mirrorservice.org/sites/ftp.debian.org/debian/ +http://uk.mirrors.clouvider.net/debian/ +http://ukdebian.mirror.anlx.net/debian/ +#LOC:GE +http://debian.grena.ge/debian/ +#LOC:GR +http://debian.otenet.gr/debian/ +#LOC:HK +http://ftp.hk.debian.org/debian/ +http://mirror.xtom.com.hk/debian/ +#LOC:HR +http://debian.carnet.hr/debian/ +http://debian.iskon.hr/debian/ +http://ftp.hr.debian.org/debian/ +#LOC:HU +http://ftp.bme.hu/debian/ +http://repo.jztkft.hu/debian/ +#LOC:ID +http://kartolo.sby.datautama.net.id/debian/ +http://kebo.pens.ac.id/debian/ +http://mirror.poliwangi.ac.id/debian/ +http://mirror.unair.ac.id/debian/ +http://mr.heru.id/debian/ +#LOC:IL +http://debian.interhost.co.il/debian/ +#LOC:IN +http://mirrors.iitd.ac.in/debian/ +#LOC:IR +http://debian.hostiran.ir/debian/ +http://debian.parspack.com/debian/ +#LOC:IS +http://ftp.is.debian.org/debian/ +http://is.mirror.flokinet.net/debian/ +#LOC:IT +http://debian.dynamica.it/debian/ +http://debian.mirror.garr.it/debian/ +http://ftp.it.debian.org/debian/ +http://ftp.linux.it/debian/ +http://giano.com.dist.unige.it/debian/ +http://mirror.units.it/debian/ +#LOC:JP +http://debian-mirror.sakura.ne.jp/debian/ +http://ftp.jp.debian.org/debian/ +http://ftp.kddilabs.jp/pub/debian/ +http://ftp.nara.wide.ad.jp/debian/ +http://ftp.riken.jp/Linux/debian/debian/ +http://mirrors.xtom.jp/debian/ +http://repo.jing.rocks/debian/ +#LOC:KE +http://debian.mirror.ac.ke/debian/ +http://debian.mirror.liquidtelecom.com/debian/ +#LOC:KR +http://ftp.kaist.ac.kr/debian/ +http://ftp.kr.debian.org/debian/ +http://mirror.siwoo.org/debian/ +#LOC:KZ +http://mirror.hoster.kz/debian/ +http://mirror.ps.kz/debian/ +#LOC:LT +http://debian.balt.net/debian/ +http://debian.mirror.vu.lt/debian/ +http://ftp.lt.debian.org/debian/ +http://mirror.litnet.lt/debian/ +http://mirror.vpsnet.com/debian/ +#LOC:LU +http://debian.mirror.root.lu/debian/ +#LOC:LV +http://debian.koyanet.lv/debian/ +http://mirror.cloudhosting.lv/debian/ +#LOC:MA +http://mirror.marwan.ma/debian/ +#LOC:MD +http://ftp.md.debian.org/debian/ +http://mirror.as43289.net/debian/ +#LOC:MK +http://mirror-mk.interspace.com/debian/ +http://mirror.onevip.mk/debian/ +#LOC:NC +http://debian.nautile.nc/debian/ +http://ftp.nc.debian.org/debian/ +http://mirror.lagoon.nc/debian/ +#LOC:NL +http://debian.snt.utwente.nl/debian/ +http://ftp.nl.debian.org/debian/ +http://mirror.duocast.net/debian/ +http://mirror.i3d.net/debian/ +http://mirror.nl.datapacket.com/debian/ +http://mirror.nl.leaseweb.net/debian/ +http://mirror.seedvps.com/debian/ +http://mirrors.hostiserver.com/debian/ +http://mirrors.xtom.nl/debian/ +http://nl.mirrors.clouvider.net/debian/ +#LOC:NO +http://ftp.no.debian.org/debian/ +http://ftp.uio.no/debian/ +#LOC:NZ +http://ftp.nz.debian.org/debian/ +http://linux.purple-cat.net/debian/ +http://mirror.fsmg.org.nz/debian/ +#LOC:PL +http://debian.inhost.pro/debian/ +http://ftp.agh.edu.pl/debian/ +http://ftp.icm.edu.pl/pub/Linux/debian/ +http://ftp.pl.debian.org/debian/ +http://ftp.psnc.pl/debian/ +http://ftp.task.gda.pl/debian/ +#LOC:PT +http://debian.uevora.pt/debian/ +http://ftp.eq.uc.pt/software/Linux/debian/ +http://ftp.pt.debian.org/debian/ +http://mirrors.ptisp.pt/debian/ +http://mirrors.up.pt/debian/ +#LOC:RE +http://debian.mithril.re/debian/ +http://depot-debian.univ-reunion.fr/debian/ +#LOC:RO +http://mirror.linux.ro/debian/ +http://mirrors.hostico.ro/debian/ +http://mirrors.nav.ro/debian/ +http://mirrors.nxthost.com/debian/ +http://ro.mirror.flokinet.net/debian/ +#LOC:RU +http://ftp.psn.ru/debian/ +http://ftp.ru.debian.org/debian/ +http://mirror.corbina.net/debian/ +http://mirror.docker.ru/debian/ +http://mirror.hyperdedic.ru/debian/ +http://mirror.mephi.ru/debian/ +http://mirrors.powernet.com.ru/debian/ +#LOC:SE +http://debian.lth.se/debian/ +http://debian.mirror.su.se/debian/ +http://ftp.acc.umu.se/debian/ +http://ftp.se.debian.org/debian/ +http://ftpmirror1.infania.net/debian/ +http://mirror.zetup.net/debian/ +http://mirrors.glesys.net/debian/ +#LOC:SG +http://mirror.coganng.com/debian/ +http://ossmirror.mycloud.services/debian/ +#LOC:SI +http://ftp.si.debian.org/debian/ +#LOC:SK +http://deb.bbxnet.sk/debian/ +http://ftp.antik.sk/debian/ +http://ftp.debian.sk/debian/ +http://ftp.sk.debian.org/debian/ +#LOC:TH +http://ftp.debianclub.org/debian/ +http://mirror.applebred.net/debian/ +http://mirror.kku.ac.th/debian/ +#LOC:TR +http://debian.gnu.gen.tr/debian/ +http://ftp.linux.org.tr/debian/ +http://ftp.tr.debian.org/debian/ +#LOC:TW +http://debian.cs.nycu.edu.tw/debian/ +http://debian.csie.ntu.edu.tw/debian/ +http://ftp.tku.edu.tw/debian/ +http://ftp.tw.debian.org/debian/ +http://opensource.nchc.org.tw/debian/ +http://tw1.mirror.blendbyte.net/debian/ +#LOC:UA +http://debian.netforce.hosting/debian/ +http://debian.volia.net/debian/ +http://fastmirror.pp.ua/debian/ +http://mirror.mirohost.net/debian/ +http://mirror.ukrnames.com/debian/ +#LOC:US +http://atl.mirrors.clouvider.net/debian/ +http://debian-archive.trafficmanager.net/debian/ +http://debian.cc.lehigh.edu/debian/ +http://debian.cs.binghamton.edu/debian/ +http://debian.csail.mit.edu/debian/ +http://debian.mirror.constant.com/debian/ +http://debian.osuosl.org/debian/ +http://debian.uchicago.edu/debian/ +http://ftp.us.debian.org/debian/ +http://la.mirrors.clouvider.net/debian/ +http://mirror.0x626b.com/debian/ +http://mirror.clarkson.edu/debian/ +http://mirror.cogentco.com/debian/ +http://mirror.dal.nexril.net/debian/ +http://mirror.keystealth.org/debian/ +http://mirror.rustytel.net/debian/ +http://mirror.siena.edu/debian/ +http://mirror.steadfast.net/debian/ +http://mirror.us.leaseweb.net/debian/ +http://mirror.us.oneandone.net/debian/ +http://mirrors.accretive-networks.net/debian/ +http://mirrors.lug.mtu.edu/debian/ +http://mirrors.namecheap.com/debian/ +http://mirrors.ocf.berkeley.edu/debian/ +http://mirrors.vcea.wsu.edu/debian/ +http://mirrors.wikimedia.org/debian/ +http://mirrors.xtom.com/debian/ +http://nyc.mirrors.clouvider.net/debian/ +http://plug-mirror.rcac.purdue.edu/debian/ +http://repo.ialab.dsu.edu/debian/ +#LOC:UY +http://debian.repo.cure.edu.uy/debian/ +#LOC:VN +http://mirror.bizflycloud.vn/debian/ +http://mirrors.bkns.vn/debian/ +#LOC:ZA +http://debian.saix.net/ +http://ftp.is.co.za/debian/ diff --git a/data/templates/Kali.info.in b/data/templates/Kali.info.in new file mode 100644 index 0000000..d817c53 --- /dev/null +++ b/data/templates/Kali.info.in @@ -0,0 +1,32 @@ +_ChangelogURI: http://pkg.kali.org/media/packages/%s/%s/%s/%s/changelog-%s + +Suite: kali-rolling +RepositoryType: deb +BaseURI: http://http.kali.org/kali/ +MatchURI: (kali\.download|(archive.*|http)\.kali\.org) +MirrorsFile: Kali.mirrors +_Description: Kali Rolling +Component: main +_CompDescription: Officially supported +Component: contrib +_CompDescription: DFSG-compatible Software with Non-Free Dependencies +Component: non-free +_CompDescription: Non-DFSG-compatible Software + +Suite: kali-dev +RepositoryType: deb +BaseURI: http://http.kali.org/kali/ +MatchURI: (kali\.download|(archive.*|http)\.kali\.org) +MirrorsFile: Kali.mirrors +_Description: Kali Development Release +Component: main +_CompDescription: Officially supported +Component: contrib +_CompDescription: DFSG-compatible Software with Non-Free Dependencies +Component: non-free +_CompDescription: Non-DFSG-compatible Software + +Suite: kali-experimental +RepositoryType: deb +ParentSuite: kali-dev +_Description: Kali Experimental Release diff --git a/data/templates/Kali.mirrors b/data/templates/Kali.mirrors new file mode 100644 index 0000000..419fb1e --- /dev/null +++ b/data/templates/Kali.mirrors @@ -0,0 +1,2 @@ +http://http.kali.org/kali/ +http://kali.download/kali/ diff --git a/data/templates/README.templates b/data/templates/README.templates new file mode 100644 index 0000000..276b674 --- /dev/null +++ b/data/templates/README.templates @@ -0,0 +1,59 @@ +Channel Definition +------------------ + +The .info files allow to specify a set of default channels that is available +in the dialog "add channel". The .info file whose name corresponds to the +LSB release name is used, e.g. 'Ubuntu.info' on a Ubuntu system. + +Furthermore all .info files are used to render the channels presented in the +sources list more user friendly. + +Abstract paragraphs +------------------- +If the Suite name contains a {, the entire paragraph becomes a template +that gets formatted with distro-info-data data. See the Ubuntu.info.in +and Debian.info.in for examples. + +Note that in such a case, if these paragraphs use { in their values for +non-template things, such as in regular expressions; they need to be +escaped - { to {{ and } to }}. + +Abstract paragraphs can only be in the middle of the file, the head and the +tail are copied unmodified. If abstract paragraphs are interleaved with +concrete ones, the behavior is undefined. + +Tags +---- + +Suite: the name of the dist used in the repository + +MatchSuite: mainly used for cdroms. defaults to Suite + +ParentSuite: the channel only appears as a component of the parent suite in + the add dialog + the components/sections of the suite correspond to the ones of + the parent suite. specified components of the suite itself + are ignored + +Available: determs the availabilty of the suite in the add dialog. + defaults to False + +RepositoryType: does the repository contain binary or source packages + +BaseURI: the base URI of the repository + +MatchURI: used for identifing mirrors + +Description: description of the suite. the translation is done through + gettext at runtime + +Component: a component/section of the suite (ignored if ParentSuite is + set) + +CompDescription: humand readable description of the component/section + (ignored if ParentSuite is set). the translation is done + through gettext at runtime + +ValidMirros: A file that contains a list of mirrors + + diff --git a/data/templates/Tanglu.info.in b/data/templates/Tanglu.info.in new file mode 100644 index 0000000..df37083 --- /dev/null +++ b/data/templates/Tanglu.info.in @@ -0,0 +1,42 @@ +_ChangelogURI: http://changelogs.tanglu.org/changelogs/%s/%s/%s/%s_%s/changelog + +Suite: aequorea +RepositoryType: deb +BaseURI: http://archive.tanglu.org/tanglu/ +MatchURI: archive.tanglu.org/tanglu +MirrorsFile: Tanglu.mirrors +_Description: Tanglu 1.0 'Aequorea' +Component: main +_CompDescription: Officially supported +Component: contrib +_CompDescription: DFSG-compatible Software with Non-Free Dependencies +Component: non-free +_CompDescription: Non-DFSG-compatible Software + +Suite: aequorea-updates +RepositoryType: deb +ParentSuite: aequorea +_Description: Recommended updates + +Suite: bartholomea +RepositoryType: deb +BaseURI: http://archive.tanglu.org/tanglu/ +MatchURI: archive.tanglu.org/tanglu +MirrorsFile: Tanglu.mirrors +_Description: Tanglu 2.0 'Bartholomea' +Component: main +_CompDescription: Officially supported +Component: contrib +_CompDescription: DFSG-compatible Software with Non-Free Dependencies +Component: non-free +_CompDescription: Non-DFSG-compatible Software + +Suite: bartholomea-security +RepositoryType: deb +ParentSuite: bartholomea +_Description: Security updates + +Suite: bartholomea-updates +RepositoryType: deb +ParentSuite: bartholomea +_Description: Recommended updates diff --git a/data/templates/Tanglu.mirrors b/data/templates/Tanglu.mirrors new file mode 100644 index 0000000..dd8ab42 --- /dev/null +++ b/data/templates/Tanglu.mirrors @@ -0,0 +1,3 @@ +#LOC:DE +http://de.archive.tanglu.org/tanglu/ +http://mirror1.hs-esslingen.de/pub/Mirrors/archive.tanglu.org/tanglu/ diff --git a/data/templates/Ubuntu.info.in b/data/templates/Ubuntu.info.in new file mode 100644 index 0000000..72c8955 --- /dev/null +++ b/data/templates/Ubuntu.info.in @@ -0,0 +1,223 @@ +_ChangelogURI: http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog + +Suite: devel +RepositoryType: deb +BaseURI: http://ports.ubuntu.com/ubuntu-ports/ +MatchURI: ports.ubuntu.com/ubuntu-ports +BaseURI-amd64: http://archive.ubuntu.com/ubuntu +MatchURI-amd64: archive.ubuntu.com/ubuntu +BaseURI-i386: http://archive.ubuntu.com/ubuntu +MatchURI-i386: archive.ubuntu.com/ubuntu +MirrorsFile-amd64: Ubuntu.mirrors +MirrorsFile-i386: Ubuntu.mirrors +_Description: Ubuntu development series +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: Canonical-supported free and open-source software +Component: universe +_CompDescription: Community-maintained +_CompDescriptionLong: Community-maintained free and open-source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices +Component: multiverse +ParentComponent: universe +_CompDescription: Restricted software +_CompDescriptionLong: Software restricted by copyright or legal issues + +Suite: devel +ParentSuite: devel +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Ubuntu development series + +Suite: devel +Official: false +RepositoryType: deb +BaseURI: http://extras.ubuntu.com +MatchURI: extras.ubuntu.com +_Description: Independent +Component: main +_CompDescription: Provided by third-party software developers +_CompDescriptionLong: Software offered by third party developers. + +Suite: devel-security +ParentSuite: devel +RepositoryType: deb +BaseURI: http://ports.ubuntu.com/ubuntu-ports/ +MatchURI: ports.ubuntu.com/ubuntu-ports +BaseURI-amd64: http://security.ubuntu.com/ubuntu/ +MatchURI-amd64: archive.ubuntu.com/ubuntu|security.ubuntu.com +BaseURI-i386: http://security.ubuntu.com/ubuntu/ +MatchURI-i386: archive.ubuntu.com/ubuntu|security.ubuntu.com +_Description: Important security updates + +Suite: devel-security +ParentSuite: devel +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports|security.ubuntu.com +_Description: Important security updates + +Suite: devel-updates +ParentSuite: devel +RepositoryType: deb +_Description: Recommended updates + +Suite: devel-updates +ParentSuite: devel +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Recommended updates + +Suite: devel-proposed +ParentSuite: devel +RepositoryType: deb +_Description: Pre-released updates + +Suite: devel-proposed +ParentSuite: devel +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Pre-released updates + +Suite: devel-backports +ParentSuite: devel +RepositoryType: deb +_Description: Unsupported updates + +Suite: devel-backports +ParentSuite: devel +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Unsupported updates + +Suite: {series} +RepositoryType: deb +BaseURI: http://ports.ubuntu.com/ubuntu-ports/ +MatchURI: ports.ubuntu.com/ubuntu-ports +BaseURI-amd64: http://archive.ubuntu.com/ubuntu +MatchURI-amd64: archive.ubuntu.com/ubuntu +BaseURI-i386: http://archive.ubuntu.com/ubuntu +MatchURI-i386: archive.ubuntu.com/ubuntu +MirrorsFile-amd64: Ubuntu.mirrors +MirrorsFile-i386: Ubuntu.mirrors +_Description: Ubuntu {version} '{codename}' +Component: main +_CompDescription: Officially supported +_CompDescriptionLong: Canonical-supported free and open-source software +Component: universe +_CompDescription: Community-maintained +_CompDescriptionLong: Community-maintained free and open-source software +Component: restricted +_CompDescription: Non-free drivers +_CompDescriptionLong: Proprietary drivers for devices +Component: multiverse +ParentComponent: universe +_CompDescription: Restricted software +_CompDescriptionLong: Software restricted by copyright or legal issues + +Suite: {series} +ParentSuite: {series} +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Ubuntu {version} '{codename}' +X-Version: ge 11.04 + +Suite: {series} +RepositoryType: deb +MatchName: .* +BaseURI: cdrom:\[Ubuntu.*{version} +MatchURI: cdrom:\[Ubuntu.*{version} +_Description: Installation medium with Ubuntu {version} '{codename}' +Available: False +Component: main +_CompDescription: Officially supported +Component: restricted +_CompDescription: Restricted copyright + +Suite: {series} +Official: false +RepositoryType: deb +BaseURI: http://archive.canonical.com +MatchURI: archive.canonical.com +_Description: Canonical Partners +Component: partner +_CompDescription: Software packaged by Canonical for their partners +_CompDescriptionLong: This software is not part of Ubuntu. +X-Version: le 20.04, ge 10.10 + +Suite: {series} +Official: false +RepositoryType: deb +BaseURI: http://extras.ubuntu.com +MatchURI: extras.ubuntu.com +_Description: Independent +Component: main +_CompDescription: Provided by third-party software developers +_CompDescriptionLong: Software offered by third party developers. +X-Version: le 15.04, ge 10.10 + +Suite: {series}-security +ParentSuite: {series} +RepositoryType: deb +BaseURI: http://ports.ubuntu.com/ubuntu-ports/ +MatchURI: ports.ubuntu.com/ubuntu-ports +BaseURI-amd64: http://security.ubuntu.com/ubuntu/ +MatchURI-amd64: archive.ubuntu.com/ubuntu|security.ubuntu.com +BaseURI-i386: http://security.ubuntu.com/ubuntu/ +MatchURI-i386: archive.ubuntu.com/ubuntu|security.ubuntu.com +_Description: Important security updates + +Suite: {series}-security +ParentSuite: {series} +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports|security.ubuntu.com +_Description: Important security updates +X-Version: ge 11.04 + +Suite: {series}-updates +ParentSuite: {series} +RepositoryType: deb +_Description: Recommended updates + +Suite: {series}-updates +ParentSuite: {series} +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Recommended updates +X-Version: ge 11.04 + +Suite: {series}-proposed +ParentSuite: {series} +RepositoryType: deb +_Description: Pre-released updates + +Suite: {series}-proposed +ParentSuite: {series} +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Pre-released updates +X-Version: ge 11.04 + +Suite: {series}-backports +ParentSuite: {series} +RepositoryType: deb +_Description: Unsupported updates + +Suite: {series}-backports +ParentSuite: {series} +RepositoryType: deb-src +BaseURI: http://archive.ubuntu.com/ubuntu/ +MatchURI: archive.ubuntu.com/ubuntu|ports.ubuntu.com/ubuntu-ports +_Description: Unsupported updates +X-Version: ge 11.04 + diff --git a/data/templates/Ubuntu.mirrors b/data/templates/Ubuntu.mirrors new file mode 100644 index 0000000..651b069 --- /dev/null +++ b/data/templates/Ubuntu.mirrors @@ -0,0 +1,665 @@ +mirror://mirrors.ubuntu.com/mirrors.txt +#LOC:AM +http://mirrors.asnet.am/ubuntu/ +http://ubuntu.mirror.gnc.am/ubuntu/ +#LOC:AR +http://ubuntu.unc.edu.ar/ubuntu/ +https://mirror.sitsa.com.ar/ubuntu/ +https://mirrors.dc.clear.net.ar/ubuntu/ +https://ubuntu.zero.com.ar/ubuntu/ +#LOC:AT +http://mirror.easyname.at/ubuntu-archive/ +http://ubuntu.lagis.at/ubuntu/ +http://ubuntu.uni-klu.ac.at/ubuntu/ +https://mirror.alwyzon.net/ubuntu/ +https://ubuntu.anexia.at/ubuntu/ +#LOC:AU +http://ftp.iinet.net.au/pub/ubuntu/ +http://mirror.aarnet.edu.au/pub/ubuntu/archive/ +http://mirror.internode.on.net/pub/ubuntu/ubuntu/ +http://mirror.netspace.net.au/pub/ubuntu/ +http://mirror.overthewire.com.au/ubuntu/ +https://mirror.datamossa.io/ubuntu/archive/ +https://mirror.gsl.icu/ubuntu/ +https://mirror.internet.asn.au/pub/ubuntu/archive/ +https://mirror.realcompute.io/ubuntu/ +https://ubuntu.mirror.digitalpacific.com.au/archive/ +https://ubuntu.mirror.serversaustralia.com.au/ubuntu/ +#LOC:AZ +http://aze.archive.ubuntu.com/ubuntu/ +http://mirror.datacenter.az/ubuntu/ +#LOC:BA +http://archive.ubuntu.mirror.ba/ubuntu/ +#LOC:BD +https://mirror.xeonbd.com/ubuntu-archive/ +#LOC:BE +http://ftp.belnet.be/ubuntu/ +http://mirror.unix-solutions.be/ubuntu/ +https://mirrors-ubuntu.behostings.com/ubuntu/ +#LOC:BG +http://mirror.bg.host.ag/ubuntu/ +http://mirrors.neterra.net/ubuntu/ +http://ubuntu.ipacct.com/ubuntu/ +https://mirror.telepoint.bg/ubuntu/ +https://mirrors.storpool.com/ubuntu/archive/ +#LOC:BR +http://mirror.ufam.edu.br/ubuntu/ +http://mirror.ufscar.br/ubuntu/ +http://mirror.unesp.br/ubuntu/ +http://sft.if.usp.br/ubuntu/ +http://ubuntu-archive.locaweb.com.br/ubuntu/ +http://ubuntu.c3sl.ufpr.br/ubuntu/ +http://ubuntu.mti.mt.gov.br/ +https://mirror.uepg.br/ubuntu/ +https://ubuntu.letscloud.io/ubuntu/ +#LOC:BW +http://mirror.retentionrange.co.bw/ubuntu/ +#LOC:BY +http://ftp.byfly.by/ubuntu/ +http://mirror.datacenter.by/ubuntu/ +#LOC:CA +http://archive.ubuntu.mirror.rafal.ca/ubuntu/ +http://mirror.ca-tr.kamatera.com/ubuntu/ +http://mirror.its.dal.ca/ubuntu/ +http://mirror.rcg.sfu.ca/mirror/ubuntu/ +http://mirrors.layeronline.com/ubuntu/ +http://ubuntu.mirror.globo.tech/ +http://ubuntu.mirror.rafal.ca/ubuntu/ +https://gpl.savoirfairelinux.net/pub/mirrors/ubuntu/ +https://mirror.0xem.ma/ubuntu/ +https://mirror.csclub.uwaterloo.ca/ubuntu/ +https://mirror.digitaloceans.dev/ubuntu/ +https://mirror.hep.gg/ubuntu/ +https://mirror.it.ubc.ca/ubuntu/ +https://mirror.reenigne.net/ubuntu/ +https://mirror01-pcl-ott1.accuris.ca/ubuntu/ +https://muug.ca/mirror/ubuntu/ +#LOC:CD +https://mirrors.united.cd/ubuntu/ +#LOC:CH +http://archive.ubuntu.csg.uzh.ch/ubuntu/ +http://mirror.infomaniak.ch/ubuntu/ +http://pkg.adfinis.com/ubuntu/ +http://ubuntu.ethz.ch/ubuntu/ +https://mirror.init7.net/ubuntu/ +https://mirror.solnet.ch/ubuntu/ +#LOC:CL +http://mirror.uchile.cl/ubuntu/ +https://mirror.hnd.cl/ubuntu/ +https://mirror.ufro.cl/ubuntu/ +#LOC:CN +http://ftp.sjtu.edu.cn/ubuntu/ +http://mirror.lzu.edu.cn/ubuntu/ +http://mirrors.aliyun.com/ubuntu/ +http://mirrors.cn99.com/ubuntu/ +http://mirrors.cqu.edu.cn/ubuntu/ +http://mirrors.huaweicloud.com/repository/ubuntu/ +http://mirrors.sohu.com/ubuntu/ +http://mirrors.yun-idc.com/ubuntu/ +https://mirror.nju.edu.cn/ubuntu/ +https://mirror.nyist.edu.cn/ubuntu/ +https://mirrors.bfsu.edu.cn/ubuntu/ +https://mirrors.bupt.edu.cn/ubuntu/ +https://mirrors.cloud.tencent.com/ubuntu/ +https://mirrors.jlu.edu.cn/ubuntu/ +https://mirrors.jxust.edu.cn/ubuntu/ +https://mirrors.tuna.tsinghua.edu.cn/ubuntu-ports/ +https://mirrors.tuna.tsinghua.edu.cn/ubuntu/ +https://mirrors.ustc.edu.cn/ubuntu/ +https://mirrors.xjtu.edu.cn/ubuntu/ +https://mirrors.zju.edu.cn/ubuntu/ +https://repo.huaweicloud.com/ubuntu/ +#LOC:CO +http://mirror.unimagdalena.edu.co/ubuntu/ +https://edgeuno-bog2.mm.fcix.net/ubuntu/ +#LOC:CR +http://ubuntu.ucr.ac.cr/ubuntu/ +#LOC:CY +http://mirror.library.ucy.ac.cy/linux/ubuntu/archive/ +#LOC:CZ +http://ftp.cvut.cz/ubuntu/ +http://ftp.linux.cz/pub/linux/ubuntu/ +http://ucho.ignum.cz/ubuntu/ +https://cz.archive.ubuntu.com/ubuntu/ +https://ftp.sh.cvut.cz/ubuntu/ +https://mirror.dkm.cz/ubuntu/ +https://mirror.it4i.cz/ubuntu/ +#LOC:DE +ftp://ftp.fu-berlin.de/linux/ubuntu/ +ftp://ftp.rrzn.uni-hannover.de/pub/mirror/linux/ubuntu +http://artfiles.org/ubuntu.com/ +http://ftp-stud.hs-esslingen.de/ubuntu/ +http://ftp.fau.de/ubuntu/ +http://ftp.halifax.rwth-aachen.de/ubuntu/ +http://ftp.hosteurope.de/mirror/archive.ubuntu.com/ +http://ftp.rrzn.uni-hannover.de/pub/mirror/linux/ubuntu/ +http://ftp.rz.tu-bs.de/pub/mirror/ubuntu-packages/ +http://ftp.stw-bonn.de/ubuntu/ +http://ftp.tu-chemnitz.de/pub/linux/ubuntu-ports/ +http://ftp.tu-chemnitz.de/pub/linux/ubuntu/ +http://ftp.tu-ilmenau.de/mirror/ubuntu/ +http://ftp.uni-bayreuth.de/linux/ubuntu/ubuntu/ +http://ftp.uni-kl.de/pub/linux/ubuntu/ +http://ftp.uni-mainz.de/ubuntu/ +http://ftp5.gwdg.de/pub/linux/debian/ubuntu/ +http://mirror.daniel-jost.net/ubuntu/ +http://mirror.eu-fr.kamatera.com/ubuntu/ +http://mirror.funkfreundelandshut.de/ubuntu/ +http://mirror.ipb.de/ubuntu/ +http://mirror.kamp.de/ubuntu/ +http://mirror.serverloft.eu/ubuntu/ubuntu/ +http://mirror.wtnet.de/ubuntu/ +http://mirror2.tuxinator.org/ubuntu/ +http://packages.oth-regensburg.de/ubuntu/ +http://suse.uni-leipzig.de/pub/releases.ubuntu.com/ubuntu/ +http://ubuntu.mirror.lrz.de/ubuntu/ +http://ubuntu.mirror.tudos.de/ubuntu/ +https://de.mirrors.clouvider.net/ubuntu/ +https://debian.charite.de/ubuntu/ +https://drmirror.physi.uni-heidelberg.de/ubuntu/ +https://ftp.uni-stuttgart.de/ubuntu/ +https://mirror.23m.com/ubuntu/ +https://mirror.creoline.net/ubuntu/ +https://mirror.de.leaseweb.net/ubuntu/ +https://mirror.dogado.de/ubuntu/ +https://mirror.informatik.tu-freiberg.de/ubuntu/ +https://mirror.kkg.berlin/ubuntu/ +https://mirror.netcologne.de/ubuntu/ +https://mirror.netzwerge.de/ubuntu/ +https://mirror.scaleuptech.com/ubuntu/ +https://mirror.united-gameserver.de/ubuntu/ +https://mirrors.xtom.de/ubuntu/ +#LOC:DK +http://ftp.klid.dk/ftp/ubuntu/ +http://mirror.one.com/ubuntu/ +http://mirrors.dotsrc.org/ubuntu/ +https://mirror.asergo.com/ubuntu/ +https://mirror.netsite.dk/ubuntu/archive/ +https://mirrors.c0urier.net/linux/ubuntu/ +#LOC:EC +http://mirror.cedia.org.ec/ubuntu/ +http://mirror.espol.edu.ec/ubuntu/ +#LOC:EE +https://mirrors.xtom.ee/ubuntu/ +#LOC:ES +http://dafi.inf.um.es/ubuntu/ +http://ftp.caliu.cat/pub/distribucions/ubuntu/archive/ +http://ftp.udc.es/ubuntu/ +http://mirror.tedra.es/ubuntu/ +http://softlibre.unizar.es/ubuntu/archive/ +http://ubuntu.cica.es/ubuntu/ +http://ubuntu.grn.cat/ubuntu/ +https://ftp.csuc.cat/ubuntu/archive/ +https://labs.eif.urjc.es/mirror/ubuntu/ +https://ubuntu.uvigo.es/ +#LOC:FI +http://mirrors.nic.funet.fi/ubuntu/ +https://mirror.5i.fi/ubuntu/ +#LOC:FR +http://distrib-coffee.ipsl.jussieu.fr/pub/linux/ubuntu/ +http://miroir.univ-lorraine.fr/ubuntu/ +http://mirror.plusserver.com/ubuntu/ubuntu/ +http://mirrors.ircam.fr/pub/ubuntu/archive/ +http://ubuntu.mirror.serverloft.de/ubuntu/ +http://ubuntu.univ-nantes.fr/ubuntu/ +http://ubuntu.univ-reims.fr/ubuntu/ +https://ftp.u-picardie.fr/mirror/ubuntu/ubuntu/ +https://mirror.johnnybegood.fr/ubuntu/ +https://mirror.ubuntu.ikoula.com/ +https://ubuntu.lafibre.info/ubuntu/ +https://ubuntu.mirrors.ovh.net/ubuntu/ +https://www-ftp.lip6.fr/pub/linux/distributions/Ubuntu/archive/ +#LOC:GB +http://archive.ubuntu.com/ubuntu/ +http://mirror.as29550.net/archive.ubuntu.com/ +http://mirror.bytemark.co.uk/ubuntu/ +http://mirror.cov.ukservers.com/ubuntu/ +http://mirror.eu-lo.kamatera.com/ubuntu/ +http://mirror.freethought-internet.co.uk/ubuntu/ +http://mirror.mythic-beasts.com/ubuntu/ +http://mirror.ox.ac.uk/sites/archive.ubuntu.com/ubuntu/ +http://mirror.sov.uk.goscomb.net/ubuntu/ +http://mirror.vorboss.net/ubuntu-archive/ +http://mirrors.coreix.net/ubuntu/ +http://mirrors.melbourne.co.uk/ubuntu/ +http://mirrors.ukfast.co.uk/sites/archive.ubuntu.com/ +http://ubuntu.mirrors.uk2.net/ubuntu/ +http://ubuntu.positive-internet.com/ubuntu/ +http://www.mirrorservice.org/sites/archive.ubuntu.com/ubuntu/ +https://mirror.vinehost.net/ubuntu/ +https://mirrors.gethosted.online/ubuntu/ +https://uk.mirrors.clouvider.net/ubuntu/ +#LOC:GE +http://ubuntu.grena.ge/ubuntu/ +#LOC:GL +http://mirror.greennet.gl/ubuntu/ +#LOC:GR +http://ftp.cc.uoc.gr/mirrors/linux/ubuntu/packages/ +http://ftp.ntua.gr/ubuntu/ +http://ubuntu.otenet.gr/ +#LOC:HK +http://mirror-hk.koddos.net/ubuntu/ +http://mirror.as.kamatera.com/ubuntu/ +https://mirror.xtom.com.hk/ubuntu/ +#LOC:HR +http://ubuntu.grad.hr/ubuntu/ +#LOC:HU +http://repo.jztkft.hu/ubuntu/ +https://mirror.niif.hu/ubuntu/ +https://mirrors.sth.sze.hu/ubuntu/ +https://quantum-mirror.hu/mirrors/pub/ubuntu/ +#LOC:ID +http://kartolo.sby.datautama.net.id/ubuntu/ +http://kebo.pens.ac.id/ubuntu/ +http://mirror.biznetgio.com/ubuntu/ +http://mirror.cepatcloud.id/ubuntu/ +http://mirror.cloudxchange.id/ubuntu/ +http://mirror.deace.id/ubuntu/ +http://mirror.poliwangi.ac.id/ubuntu/ +http://mirror.unej.ac.id/ubuntu/ +http://repo.ugm.ac.id/ubuntu/ +http://suro.ubaya.ac.id/ubuntu/ +https://buaya.klas.or.id/ubuntu/ +https://cdn.repo.cloudeka.id/ubuntu/ +https://cdn.ubuntu.repo.cloudeka.id/ubuntu/ +https://linux.domainesia.com/ubuntu/ubuntu-archive/ +https://mirror.amscloud.co.id/ubuntu/ +https://mirror.citrahost.com/ubuntu/ +https://mirror.faizuladib.com/ubuntu/ +https://mirror.gi.co.id/ubuntu/ +https://mirror.nevacloud.com/ubuntu/ubuntu-archive/ +https://mirror.papua.go.id/ubuntu/ +https://mirror.repository.id/ubuntu/ +https://mirror.unair.ac.id/ubuntu/ +https://mirrors.idcloudhost.com/ubuntu/ +https://mr.heru.id/ubuntu/ +https://repo.usk.ac.id/ubuntu/ +https://sby.mirror.bignet.id/ubuntu/ +#LOC:IE +http://ftp.heanet.ie/pub/ubuntu/ +https://mirror.webworld.ie/ubuntu/ +#LOC:IL +http://mirror.il-jr.kamatera.com/ubuntu/ +http://mirror.il-pt.kamatera.com/ubuntu/ +http://mirror.il-rh.kamatera.com/ubuntu/ +http://mirror.il-ta.kamatera.com/ubuntu/ +http://mirror.il.kamatera.com/ubuntu/ +http://mirror.isoc.org.il/pub/ubuntu/ +http://rep-ubuntu-il.upress.io/ubuntu/ +https://ubuntu-archive.interhost.co.il/ubuntu/ +#LOC:IN +http://ftp.iitm.ac.in/ubuntu/ +http://mirror.cse.iitk.ac.in/ubuntu/ +http://mirrors.iitd.ac.in/ubuntu/ +http://mirrors.piconets.webwerks.in/ubuntu-mirror/ubuntu/ +http://repos.del.extreme-ix.org/ubuntu/ +https://in.mirror.coganng.com/ubuntu-ports/ +https://in.mirror.coganng.com/ubuntu/ +https://mirror.nitc.ac.in/ubuntu/ +https://mirrors.nxtgen.com/ubuntu-mirror/ubuntu/ +https://repo.extreme-ix.org/ubuntu/ +https://ubuntu-archive.mirror.net.in/ +https://ubuntu-ports.mirror.net.in/ +#LOC:IR +http://linuxmirrors.ir/pub/ubuntu/ +http://mirror.aminidc.com/ubuntu/ +http://mirror.faraso.org/ubuntu/ +http://repo.iut.ac.ir/repo/Ubuntu/ +http://ubuntu.byteiran.com/ubuntu/ +https://archive.ubuntu.petiak.ir/ubuntu/ +https://ir.archive.ubuntu.com/ubuntu/ +https://ir.ubuntu.sindad.cloud/ubuntu/ +https://mirror.0-1.cloud/ubuntu/ +https://mirror.iranserver.com/ubuntu/ +https://mirror.rasanegar.com/ubuntu/ +https://mirrors.pardisco.co/ubuntu/ +https://ubuntu-mirror.kimiahost.com/ +https://ubuntu.bardia.tech/ +https://ubuntu.hostiran.ir/ubuntuarchive/ +https://ubuntu.shatel.ir/ubuntu/ +#LOC:IS +http://ubuntu.hysing.is/ubuntu/ +https://is.mirror.flokinet.net/ubuntu/ +https://mirrors.opensource.is/ubuntu/ +#LOC:IT +http://giano.com.dist.unige.it/ubuntu/ +https://it1.mirror.vhosting-it.com/ubuntu/ +https://it2.mirror.vhosting-it.com/ubuntu/ +https://ubuntu.mirror.garr.it/ubuntu/ +#LOC:JP +http://archive.g4t1.pro/ubuntu/ +http://ftp.jaist.ac.jp/pub/Linux/ubuntu/ +http://ftp.riken.jp/Linux/ubuntu/ +http://ftp.tsukuba.wide.ad.jp/Linux/ubuntu/ +http://ubuntutym.u-toyama.ac.jp/ubuntu/ +http://www.ftp.ne.jp/Linux/packages/ubuntu/archive/ +https://ftp.udx.icscoe.jp/Linux/ubuntu/ +https://jp.mirror.coganng.com/ubuntu-ports/ +https://jp.mirror.coganng.com/ubuntu/ +https://linux.yz.yamagata-u.ac.jp/ubuntu/ +https://mirror.nishi.network/ubuntu-ports/ +https://mirror.nishi.network/ubuntu/ +https://repo.jing.rocks/ubuntu-ports/ +https://repo.jing.rocks/ubuntu/ +#LOC:KG +http://mir.linux.kg/ubuntu/ +#LOC:KH +https://mirror.sabay.com.kh/ubuntu/ +#LOC:KR +http://ftp.daum.net/ubuntu/ +https://ftp.kaist.ac.kr/ubuntu-ports/ +https://ftp.kaist.ac.kr/ubuntu/ +https://ftp.lanet.kr/ubuntu-ports/ +https://ftp.lanet.kr/ubuntu/ +https://mirror.elice.io/ubuntu/ +https://mirror.kakao.com/ubuntu/ +https://mirror.morgan.kr/ubuntu/ +https://mirror.siwoo.org/ubuntu/ +https://mirror.yuki.net.uk/ubuntu-ports/ +https://mirror.yuki.net.uk/ubuntu/ +#LOC:KZ +http://mirror.hoster.kz/ubuntu/ +http://mirror.neolabs.kz/ubuntu/ +http://mirror.ps.kz/ubuntu/ +#LOC:LT +http://ftp.litnet.lt/ubuntu/ +http://ubuntu-archive.mirror.serveriai.lt/ +http://ubuntu.mirror.vu.lt/ubuntu/ +https://mirror.vpsnet.com/ubuntu/ +#LOC:LU +http://ubuntu.mirror.root.lu/ubuntu/ +#LOC:LV +http://mirror.cloudhosting.lv/ubuntu/ +http://ubuntu-arch.linux.edu.lv/ubuntu/ +http://ubuntu.koyanet.lv/ubuntu/ +#LOC:MA +https://mirror.marwan.ma/ubuntu/ +#LOC:MD +http://mirror.as43289.net/ubuntu/ +http://mirrors.mivocloud.com/ubuntu/ +https://mirror.ihost.md/ubuntu/ +#LOC:MG +http://ubuntu.dts.mg/ubuntu/ +#LOC:MK +http://mirror-mk.interspace.com/ubuntu/ +http://mirror.onevip.mk/ubuntu/ +http://mirror.t-home.mk/ubuntu/ +#LOC:MM +https://mirror.ygn.mmix.net.mm/ubuntu/ +#LOC:MN +http://mirror.datacenter.mn/ubuntu/ +#LOC:MU +https://ubuntu-mirror.cloud.mu/ubuntu-ports/ +https://ubuntu-mirror.cloud.mu/ubuntu/ +#LOC:MY +http://ubuntu.tuxuri.com/ubuntu/ +https://mirrors.gbnetwork.com/ubuntu/ +https://mirrors.ipserverone.com/ubuntu/ +#LOC:NA +http://download.nust.na/pub/ubuntu/ubuntu/ +#LOC:NC +http://archive.ubuntu.nautile.nc/ubuntu/ +http://ubuntu.lagoon.nc/ubuntu/ +#LOC:NL +ftp://ftpserv.tudelft.nl/pub/Linux/archive.ubuntu.com/ +http://ftp.nluug.nl/os/Linux/distr/ubuntu/ +http://ftp.snt.utwente.nl/pub/os/linux/ubuntu/ +http://ftp.tudelft.nl/archive.ubuntu.com/ +http://mirror.eu.kamatera.com/ubuntu/ +http://mirror.hostnet.nl/ubuntu/archive/ +http://mirror.i3d.net/pub/ubuntu/ +http://mirror.nforce.com/pub/linux/ubuntu/ +http://mirror.nl.datapacket.com/ubuntu/ +http://mirror.previder.nl/ubuntu/ +http://mirror.serverion.com/ubuntu/ +http://mirror.serverius.net/ubuntu/ +http://mirror.transip.net/ubuntu/ubuntu/ +http://mirror.vpgrp.io/ubuntu/ +http://nl.archive.ubuntu.com/ubuntu/ +http://nl3.archive.ubuntu.com/ubuntu/ +http://osmirror.rug.nl/ubuntu/ +http://ubuntu.mirror.true.nl/ubuntu/ +https://mirror.lyrahosting.com/ubuntuarchive/ +https://mirror.nl.altushost.com/ubuntu/ +https://mirror.nl.leaseweb.net/ubuntu/ +https://mirrors.evoluso.com/ubuntu/ +https://mirrors.hostiserver.com/ubuntu/ +https://mirrors.xtom.nl/ubuntu/ +https://nl.mirrors.clouvider.net/ubuntu/ +https://ubuntu.mirror.intermax.nl/ +https://ubuntu.mirror.wearetriple.com/archive/ +#LOC:NO +http://ftp.uninett.no/ubuntu/ +http://no.archive.ubuntu.com/ubuntu/ +http://no.mirrors.blix.com/ubuntu/ +http://ubuntu.uib.no/archive/ +https://ubuntu.hi.no/archive/ +#LOC:NP +http://ntc.net.np/ubuntu/ +#LOC:NZ +http://ubuntu.mirrors.theom.nz/ +http://ucmirror.canterbury.ac.nz/ubuntu/ +https://mirror.2degrees.nz/ubuntu/ +https://mirror.fsmg.org.nz/ubuntu/ +#LOC:PH +http://mirror.rise.ph/ubuntu/ +#LOC:PL +http://ftp.agh.edu.pl/ubuntu/ +http://ftp.vectranet.pl/ubuntu/ +http://mirror.chmuri.net/ubuntu/ +http://ubuntu.man.lodz.pl/ubuntu/ +http://ubuntu.task.gda.pl/ubuntu/ +https://ftp.psnc.pl/linux/ubuntu/ +#LOC:PR +http://mirrors.upr.edu/ubuntu/ +#LOC:PT +http://archive.ubuntumirror.dei.uc.pt/ubuntu/ +http://cesium.di.uminho.pt/pub/ubuntu-archive/ +http://ftp.rnl.tecnico.ulisboa.pt/pub/ubuntu/archive/ +http://glua.ua.pt/pub/ubuntu/ +http://mirrors.up.pt/ubuntu/ +https://mirrors.ptisp.pt/ubuntu/ +#LOC:RO +http://mirrors.nxthost.com/ubuntu/ +http://mirrors.pidginhost.com/ubuntu/ +http://ubuntu.mirrors.linux.ro/archive/ +https://mirror.efect.ro/ubuntu/archive/ +https://mirror.flokinet.net/ubuntu/ +https://mirrors.chroot.ro/ubuntu/ +https://mirrors.hosterion.ro/ubuntu/ +https://mirrors.hostico.ro/ubuntu/archive/ +https://mirrors.layerbridge.com/ubuntu/ +https://mirrors.nav.ro/ubuntu/ +https://ubuntu-mirror.magnetic-it.com/ubuntu/ +https://ubuntu.mirrors.orange.ro/ubuntu/ +#LOC:RS +http://mirror1.sox.rs/ubuntu/ubuntu/ +https://mirror1.sox.rs/ubuntu/ubuntu/ +#LOC:RU +http://mirror.corbina.net/ubuntu/ +http://mirror.docker.ru/ubuntu/ +http://mirror.logol.ru/ubuntu/ +http://mirror.timeweb.ru/ubuntu/ +http://mirror.yandex.ru/ubuntu/ +http://mirrors.powernet.com.ru/ubuntu/ +https://mirror.hyperdedic.ru/ubuntu/ +https://mirror.linux-ia64.org/ubuntu/ +https://mirror.neftm.ru/ubuntu/ +https://mirror.truenetwork.ru/ubuntu/ +#LOC:SA +https://mirrors.isu.net.sa/apt-mirror/ +#LOC:SE +http://ftp.acc.umu.se/ubuntu/ +http://ftp.lysator.liu.se/ubuntu/ +http://mirror.zetup.net/ubuntu/ +http://ubuntu.mirror.su.se/ubuntu/ +https://ftpmirror1.infania.net/ubuntu/ +https://mirror.bahnhof.net/ubuntu/ +#LOC:SG +http://cdn.0ms.dev/ubuntu/ +http://download.nus.edu.sg/mirror/ubuntu/ +http://mirror.aktkn.sg/ubuntu/ +http://mirror.sg.gs/ubuntu/ +http://ossmirror.mycloud.services/os/linux/ubuntu/ +https://mirror.coganng.com/ubuntu-ports/ +https://mirror.coganng.com/ubuntu/ +#LOC:SI +http://ftp.arnes.si/pub/mirrors/ubuntu/ +#LOC:SK +http://ftp.energotel.sk/pub/linux/ubuntu/ +http://tux.rainside.sk/ubuntu/ +https://mirror.vnet.sk/ubuntu/ +#LOC:TH +http://ftp.psu.ac.th/pub/ubuntu/ +http://mirror.thaidns.co.th/ubuntu/ +http://mirror1.ku.ac.th/ubuntu/ +http://mirror1.totbb.net/ubuntu/ +http://mirrors.bangmod.cloud/ubuntu/ +http://mirrors.psu.ac.th/ubuntu/ +https://mirror.kku.ac.th/ubuntu/ +https://mirrors.nipa.cloud/ubuntu/ +#LOC:TR +http://mirror.kapteyan.com.tr/ubuntu/ +http://ubuntu.turhost.com/ubuntu/ +http://ubuntu.vargonen.com/ubuntu/ +https://ftp.linux.org.tr/ubuntu/ +https://kozyatagi.mirror.guzel.net.tr/ubuntu/ +https://mirror.alastyr.com/ubuntu/ubuntu-archive/ +https://mirror.rabisu.com/ubuntu/ubuntu-archive/ +https://mirror.sh.com.tr/ubuntu/ +https://mirror.verinomi.com/ubuntu/ubuntu-archive/ +#LOC:TW +http://free.nchc.org.tw/ubuntu/ +http://ftp.mirror.tw/pub/ubuntu/ubuntu/ +http://ftp.tku.edu.tw/ubuntu/ +http://ftp.tw.debian.org/ubuntu/ +http://mirror.nwlab.tk/ubuntu/ +http://mirror01.idc.hinet.net/ubuntu/ +http://ubuntu.cs.nctu.edu.tw/ubuntu/ +https://ftp.tc.edu.tw/Linux/ubuntu/ +https://ftp.ubuntu-tw.net/ubuntu/ +https://mirror.ossplanet.net/ubuntu/ +https://tw1.mirror.blendbyte.net/ubuntu/ +https://ubuntu.ccns.ncku.edu.tw/ubuntu/ +#LOC:TZ +http://deb-mirror.habari.co.tz/ubuntu/ +http://mirror.aptus.co.tz/pub/ubuntuarchive/ +#LOC:UA +http://mirror.mirohost.net/ubuntu/ +http://ubuntu.colocall.net/ubuntu/ +http://ubuntu.mirrors.omnilance.com/ubuntu/ +http://ubuntu.org.ua/ubuntu/ +http://ubuntu.volia.net/ubuntu-archive/ +https://ubuntu.ip-connect.vn.ua/ +https://ubuntu.netforce.hosting/ubuntu/ +#LOC:UG +http://mirror.renu.ac.ug/ubuntu/ +#LOC:US +http://archive.linux.duke.edu/ubuntu/ +http://babylon.cs.uh.edu/mirror-sites/ubuntu/ +http://ftp.usf.edu/pub/ubuntu/ +http://ftp.ussg.iu.edu/linux/ubuntu/ +http://mirror.arizona.edu/ubuntu/ +http://mirror.brightridge.com/ubuntuarchive/ +http://mirror.cc.vt.edu/pub2/ubuntu/ +http://mirror.cogentco.com/pub/linux/ubuntu/ +http://mirror.cs.jmu.edu/pub/ubuntu/ +http://mirror.math.princeton.edu/pub/ubuntu/ +http://mirror.math.ucdavis.edu/ubuntu/ +http://mirror.metrocast.net/ubuntu/ +http://mirror.mrjester.net/ubuntu/archive/ +http://mirror.nodesdirect.com/ubuntu/ +http://mirror.pit.teraswitch.com/ubuntu/ +http://mirror.rustytel.net/ubuntu/ +http://mirror.siena.edu/ubuntu/ +http://mirror.steadfastnet.com/ubuntu/ +http://mirror.team-cymru.com/ubuntu/ +http://mirror.team-cymru.org/ubuntu/ +http://mirror.umd.edu/ubuntu/ +http://mirror.uoregon.edu/ubuntu/ +http://mirror.us-midwest-1.nexcess.net/ubuntu/ +http://mirror.us-ny2.kamatera.com/ubuntu/ +http://mirror.us-sc.kamatera.com/ubuntu/ +http://mirror.us-tx.kamatera.com/ubuntu/ +http://mirror.vcu.edu/pub/gnu+linux/ubuntu/ +http://mirrors.accretive-networks.net/ubuntu/ +http://mirrors.advancedhosters.com/ubuntu/ +http://mirrors.arpnetworks.com/Ubuntu/ +http://mirrors.cat.pdx.edu/ubuntu/ +http://mirrors.cmich.edu/ubuntu/ +http://mirrors.codec-cluster.org/ubuntu/ +http://mirrors.gigenet.com/ubuntuarchive/ +http://mirrors.liquidweb.com/ubuntu/ +http://mirrors.lug.mtu.edu/ubuntu/ +http://mirrors.maine.edu/ubuntu/ +http://mirrors.mit.edu/ubuntu/ +http://mirrors.namecheap.com/ubuntu/ +http://mirrors.ocf.berkeley.edu/ubuntu/ +http://mirrors.rit.edu/ubuntu/ +http://mirrors.sonic.net/ubuntu/ +http://mirrors.syringanetworks.net/ubuntu-archive/ +http://mirrors.tripadvisor.com/ubuntu/ +http://mirrors.us.kernel.org/ubuntu/ +http://mirrors.usinternet.com/ubuntu/archive/ +http://mirrors.vcea.wsu.edu/ubuntu/ +http://mirrors.xmission.com/ubuntu/ +http://plug-mirror.rcac.purdue.edu/ubuntu/ +http://pubmirrors.dal.corespace.com/ubuntu/ +http://repo.miserver.it.umich.edu/ubuntu/ +http://ubuntu.cs.utah.edu/ubuntu/ +http://ubuntu.mirror.constant.com/ +http://ubuntu.mirror.frontiernet.net/ubuntu/ +http://ubuntu.mirrors.pair.com/archive/ +http://ubuntu.osuosl.org/ubuntu/ +http://ubuntu.phoenixnap.com/ubuntu/ +http://ubuntu.securedservers.com/ +http://www.club.cc.cmu.edu/pub/ubuntu/ +http://www.gtlib.gatech.edu/pub/ubuntu/ +https://atl.mirrors.clouvider.net/ubuntu/ +https://dal.mirrors.clouvider.net/ubuntu/ +https://la.mirrors.clouvider.net/ubuntu/ +https://lug.mines.edu/mirrors/ubuntu/ +https://mirror.clarkson.edu/ubuntu/ +https://mirror.cs.pitt.edu/ubuntu/archive/ +https://mirror.d.umn.edu/ubuntu/ +https://mirror.dal.nexril.net/ubuntu/ +https://mirror.enzu.com/ubuntu/ +https://mirror.fcix.net/ubuntu/ +https://mirror.hoobly.com/ubuntu/ +https://mirror.lstn.net/ubuntu/ +https://mirror.mia.velocihost.net/ubuntu/ +https://mirror.servaxnet.com/ubuntu/ +https://mirror.timkevin.us/ubuntu/ +https://mirror.ubuntu.serverforge.org/ +https://mirror.us.leaseweb.net/ubuntu/ +https://mirrors.bloomu.edu/ubuntu/ +https://mirrors.egr.msu.edu/ubuntu/ +https://mirrors.iu13.net/ubuntu/ +https://mirrors.ocf.berkeley.edu/ubuntu-ports/ +https://mirrors.sarak.as/ubuntu/ +https://mirrors.tscak.com/ubuntu/ +https://mirrors.wikimedia.org/ubuntu/ +https://mirrors.xtom.com/ubuntu/ +https://nyc.mirrors.clouvider.net/ubuntu/ +https://repo.ialab.dsu.edu/ubuntu/ +https://repos.eggycrew.com/ubuntu/ +https://ubuntu.macarne.com/ +https://ubuntu.mirror.shastacoe.net/ubuntu/ +#LOC:UY +http://repos.interior.edu.uy/ubuntu/ +https://ubuntu.repo.cure.edu.uy/ubuntu/ +#LOC:UZ +http://mirror.dc.uz/ubuntu/ +#LOC:VN +http://mirror.bizflycloud.vn/ubuntu/ +http://mirror.clearsky.vn/ubuntu/ +http://mirror.vietnix.vn/ubuntu/ +http://mirror.viettelcloud.vn/ubuntu/ +http://mirrors.vhost.vn/ubuntu/ +http://opensource.xtdv.net/ubuntu/ +https://mirror.hostingviet.vn/ubuntu/ +https://mirrors.bkns.vn/ubuntu/ +#LOC:ZA +http://mirror.hostafrica.co.za/ubuntu/ +http://ubuntu.mirror.ac.za/ubuntu/ +http://ubuntu.mirror.rain.co.za/ubuntu/ diff --git a/data/templates/gNewSense.info.in b/data/templates/gNewSense.info.in new file mode 100644 index 0000000..c7636bc --- /dev/null +++ b/data/templates/gNewSense.info.in @@ -0,0 +1,55 @@ +_ChangelogURI: http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog + +# gNS 3, to be based on Squeeze. +Suite: parkes +RepositoryType: deb +BaseURI: http://archive.gnewsense.org/gnewsense/ +MatchURI: archive.gnewsense.org/gnewsense +MirrorsFile: gNewSense.mirrors +Description: gNewSense 3 - "parkes" +Component: main +_CompDescription: Main supported software +_CompDescriptionLong: Core software + +Suite: parkes/updates +RepositoryType: deb +BaseURI: http://security.gnewsense.org/gnewsense +MatchURI: security.gnewsense.org/security +ParentSuite: parkes +_Description: Security updates + +# gNS 2.x, based on hardy +Suite: deltah +RepositoryType: deb +BaseURI: http://archive.gnewsense.org/gnewsense/ +MatchURI: archive.gnewsense.org/gnewsense +MirrorsFile: gNewSense.mirrors +_Description: gNewSense "deltah" +Component: main +_CompDescription: Main supported software +_CompDescriptionLong: Core software +Component: universe +_CompDescription: Other useful software +_CompDescriptionLong: Non-core useful software + +Suite: deltah-security +ParentSuite: deltah +RepositoryType: deb +BaseURI: http://security.gnewsense.org/gnewsense/ +MatchURI: archive.gnewsense.org/gnewsense|security.gnewsense.org +_Description: Important security updates + +Suite: deltah-updates +ParentSuite: deltah +RepositoryType: deb +BaseURI: http://archive.gnewsense.org/gnewsense/ +MatchURI: archive.gnewsense.org/gnewsense +_Description: Unsupported updates + +Suite: deltah-backports +ParentSuite: deltah +RepositoryType: deb +BaseURI: http://archive.gnewsense.org/gnewsense/ +MatchURI: archive.gnewsense.org/gnewsense +_Description: Package Backports + diff --git a/data/templates/gNewSense.mirrors b/data/templates/gNewSense.mirrors new file mode 100644 index 0000000..7a8dbaa --- /dev/null +++ b/data/templates/gNewSense.mirrors @@ -0,0 +1,489 @@ + +#LOC:AD +http://ad.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AE +http://ae.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AF +http://af.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AG +http://ag.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AI +http://ai.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AL +http://al.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AM +http://am.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AN +http://an.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AO +http://ao.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AQ +http://aq.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AR +http://ar.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AS +http://as.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AT +http://at.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AU +http://au.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AW +http://aw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AX +http://ax.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:AZ +http://az.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BA +http://ba.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BB +http://bb.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BD +http://bd.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BE +http://be.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BF +http://bf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BG +http://bg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BH +http://bh.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BI +http://bi.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BJ +http://bj.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BM +http://bm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BN +http://bn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BO +http://bo.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BR +http://br.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BS +http://bs.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BT +http://bt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BV +http://bv.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BW +http://bw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BY +http://by.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:BZ +http://bz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CA +http://ca.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CC +http://cc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CD +http://cd.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CF +http://cf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CG +http://cg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CH +http://ch.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CI +http://ci.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CK +http://ck.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CL +http://cl.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CM +http://cm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CN +http://cn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CO +http://co.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CR +http://cr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CU +http://cu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CV +http://cv.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CX +http://cx.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CY +http://cy.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:CZ +http://cz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:DE +http://de.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:DJ +http://dj.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:DK +http://dk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:DM +http://dm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:DO +http://do.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:DZ +http://dz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:EC +http://ec.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:EE +http://ee.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:EG +http://eg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:EH +http://eh.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ER +http://er.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ES +http://es.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ET +http://et.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:FI +http://fi.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:FJ +http://fj.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:FK +http://fk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:FM +http://fm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:FO +http://fo.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:FR +http://fr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GA +http://ga.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GB +http://gb.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GD +http://gd.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GE +http://ge.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GF +http://gf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GG +http://gg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GH +http://gh.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GI +http://gi.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GL +http://gl.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GM +http://gm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GN +http://gn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GP +http://gp.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GQ +http://gq.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GR +http://gr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GS +http://gs.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GT +http://gt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GU +http://gu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GW +http://gw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:GY +http://gy.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:HK +http://hk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:HM +http://hm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:HN +http://hn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:HR +http://hr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:HT +http://ht.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:HU +http://hu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ID +http://id.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IE +http://ie.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IL +http://il.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IM +http://im.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IN +http://in.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IO +http://io.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IQ +http://iq.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IR +http://ir.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IS +http://is.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:IT +http://it.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:JE +http://je.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:JM +http://jm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:JO +http://jo.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:JP +http://jp.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KE +http://ke.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KG +http://kg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KH +http://kh.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KI +http://ki.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KM +http://km.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KN +http://kn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KP +http://kp.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KR +http://kr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KW +http://kw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KY +http://ky.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:KZ +http://kz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LA +http://la.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LB +http://lb.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LC +http://lc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LI +http://li.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LK +http://lk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LR +http://lr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LS +http://ls.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LT +http://lt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LU +http://lu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LV +http://lv.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:LY +http://ly.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MA +http://ma.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MC +http://mc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MD +http://md.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ME +http://me.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MG +http://mg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MH +http://mh.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MK +http://mk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ML +http://ml.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MM +http://mm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MN +http://mn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MO +http://mo.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MP +http://mp.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MQ +http://mq.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MR +http://mr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MS +http://ms.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MT +http://mt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MU +http://mu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MV +http://mv.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MW +http://mw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MX +http://mx.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MY +http://my.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:MZ +http://mz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NA +http://na.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NC +http://nc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NE +http://ne.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NF +http://nf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NG +http://ng.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NI +http://ni.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NL +http://nl.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NO +http://no.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NP +http://np.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NR +http://nr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NU +http://nu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:NZ +http://nz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:OM +http://om.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PA +http://pa.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PE +http://pe.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PF +http://pf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PG +http://pg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PH +http://ph.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PK +http://pk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PL +http://pl.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PM +http://pm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PN +http://pn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PR +http://pr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PS +http://ps.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PT +http://pt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PW +http://pw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:PY +http://py.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:QA +http://qa.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:RE +http://re.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:RO +http://ro.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:RS +http://rs.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:RU +http://ru.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:RW +http://rw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SA +http://sa.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SB +http://sb.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SC +http://sc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SD +http://sd.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SE +http://se.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SG +http://sg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SH +http://sh.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SI +http://si.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SJ +http://sj.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SK +http://sk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SL +http://sl.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SM +http://sm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SN +http://sn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SO +http://so.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SR +http://sr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ST +http://st.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SV +http://sv.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SY +http://sy.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:SZ +http://sz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TC +http://tc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TD +http://td.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TF +http://tf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TG +http://tg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TH +http://th.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TJ +http://tj.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TK +http://tk.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TL +http://tl.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TM +http://tm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TN +http://tn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TO +http://to.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TR +http://tr.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TT +http://tt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TV +http://tv.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TW +http://tw.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:TZ +http://tz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:UA +http://ua.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:UG +http://ug.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:UM +http://um.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:US +http://us.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:UY +http://uy.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:UZ +http://uz.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VA +http://va.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VC +http://vc.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VE +http://ve.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VG +http://vg.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VI +http://vi.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VN +http://vn.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:VU +http://vu.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:WF +http://wf.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:WS +http://ws.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:YE +http://ye.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:YT +http://yt.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ZA +http://za.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ZM +http://zm.archive.gnewsense.org/gnewsense-metad/gnewsense/ +#LOC:ZW +http://zw.archive.gnewsense.org/gnewsense-metad/gnewsense/ diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000..327bba9 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,79 @@ +# Makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +PAPER = + +# Internal variables. +PAPEROPT_a4 = -D latex_paper_size=a4 +PAPEROPT_letter = -D latex_paper_size=letter +ALLSPHINXOPTS = -d build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source + +.PHONY: help clean html web pickle htmlhelp latex changes linkcheck + +help: + @echo "Please use \`make ' where is one of" + @echo " html to make standalone HTML files" + @echo " pickle to make pickle files" + @echo " json to make JSON files" + @echo " htmlhelp to make HTML files and a HTML help project" + @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" + @echo " changes to make an overview over all changed/added/deprecated items" + @echo " linkcheck to check all external links for integrity" + +clean: + -rm -rf build/* + +text: + mkdir -p build/text build/doctrees + $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) build/text + +html: + mkdir -p build/html build/doctrees + $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) build/html + @echo + @echo "Build finished. The HTML pages are in build/html." + +pickle: + mkdir -p build/pickle build/doctrees + $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) build/pickle + @echo + @echo "Build finished; now you can process the pickle files." + +web: pickle + +json: + mkdir -p build/json build/doctrees + $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) build/json + @echo + @echo "Build finished; now you can process the JSON files." + +htmlhelp: + mkdir -p build/htmlhelp build/doctrees + $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) build/htmlhelp + @echo + @echo "Build finished; now you can run HTML Help Workshop with the" \ + ".hhp project file in build/htmlhelp." + +latex: + mkdir -p build/latex build/doctrees + $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) build/latex + @echo + @echo "Build finished; the LaTeX files are in build/latex." + @echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ + "run these through (pdf)latex." + +changes: + mkdir -p build/changes build/doctrees + $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) build/changes + @echo + @echo "The overview file is in build/changes." + +linkcheck: + mkdir -p build/linkcheck build/doctrees + $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) build/linkcheck + @echo + @echo "Link check complete; look for any errors in the above output " \ + "or in build/linkcheck/output.txt." diff --git a/doc/client-example.cc b/doc/client-example.cc new file mode 100644 index 0000000..73fa3ee --- /dev/null +++ b/doc/client-example.cc @@ -0,0 +1,68 @@ +/* + * client-example.cc - A simple example for using the python-apt C++ API. + * + * Copyright 2009 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include + +// The module initialization. +extern "C" void initclient() { + if (import_apt_pkg() < 0) + return; + // Initialize a module. + PyObject *Module = Py_InitModule("client", NULL); + + // Create a HashString, which will be added to the module. + HashString *hash = new HashString("0966a120bb936bdc6fdeac445707aa6b"); + // Create a Python object for the hashstring and add it to the module + PyModule_AddObject(Module, "hash", PyHashString_FromCpp(hash, false, NULL)); + + // Another example: Add the HashString type to the module. + Py_INCREF(&PyHashString_Type); + PyModule_AddObject(Module, "HashString", (PyObject*)(&PyHashString_Type)); +} + +int main(int argc, char *argv[]) { + // Return value. + int ret = 0; + // Initialize python + Py_Initialize(); + // Make the client module importable + PyImport_AppendInittab("client", &initclient); + // Set the commandline arguments. + PySys_SetArgv(argc, argv); + + // Import the module, so the user does not have to import it. + if (PyRun_SimpleString("import client\n") < 0) { + // Failure (should never be reached) + ret = 1; + goto end; + } + + // Run IPython if available, otherwise a normal interpreter. + if (PyRun_SimpleString("from IPython.Shell import start\n") == 0) + PyRun_SimpleString("start(user_ns=dict(client=client)).mainloop()\n"); + else + Py_Main(argc, argv); + +end: + Py_Finalize(); + return ret; +} diff --git a/doc/examples/acquire.py b/doc/examples/acquire.py new file mode 100644 index 0000000..3d1e31b --- /dev/null +++ b/doc/examples/acquire.py @@ -0,0 +1,80 @@ +#!/usr/bin/python3 +import os + +import apt_pkg + +import apt +import apt.progress.text + + +def get_file(fetcher, uri, destfile): + # get the file + af = apt_pkg.AcquireFile(fetcher, uri=uri, descr="sample descr", destfile=destfile) + print(f"desc_uri: {af.desc_uri} -> {af.destfile}") + res = fetcher.run() + if res != fetcher.RESULT_CONTINUE: + return False + return True + + +apt_pkg.init() + +# apt_pkg.config.set("Debug::pkgDPkgPM","1"); +# apt_pkg.config.set("Debug::pkgPackageManager","1"); +# apt_pkg.config.set("Debug::pkgDPkgProgressReporting","1"); + +cache = apt_pkg.Cache() +depcache = apt_pkg.DepCache(cache) + +recs = apt_pkg.PackageRecords(cache) +list = apt_pkg.SourceList() +list.read_main_list() + +# show the amount fetch needed for a dist-upgrade +depcache.upgrade(True) +progress = apt.progress.text.AcquireProgress() +fetcher = apt_pkg.Acquire(progress) +pm = apt_pkg.PackageManager(depcache) +pm.get_archives(fetcher, list, recs) +print(f"{apt_pkg.size_to_str(fetcher.fetch_needed)} ({fetcher.fetch_needed})") +actiongroup = apt_pkg.ActionGroup(depcache) +for pkg in cache.packages: + depcache.mark_keep(pkg) + +try: + os.mkdir("/tmp/pyapt-test") + os.mkdir("/tmp/pyapt-test/partial") +except OSError: + pass +apt_pkg.config.set("Dir::Cache::archives", "/tmp/pyapt-test") + +pkg = cache["2vcard"] +depcache.mark_install(pkg) + +progress = apt.progress.text.AcquireProgress() +fetcher = apt_pkg.Acquire(progress) +# fetcher = apt_pkg.Acquire() +pm = apt_pkg.PackageManager(depcache) + +print(pm) +print(fetcher) + +get_file(fetcher, "ftp://ftp.debian.org/debian/dists/README", "/tmp/lala") + +pm.get_archives(fetcher, list, recs) + +for item in fetcher.items: + print(item) + if item.status == item.STAT_ERROR: + print("Some error ocured: '%s'" % item.error_text) + if not item.complete: + print("No error, still nothing downloaded (%s)" % item.error_text) + print() + + +res = fetcher.run() +print("fetcher.Run() returned: %s" % res) + +print("now runing pm.DoInstall()") +res = pm.do_install(1) +print("pm.DoInstall() returned: %s" % res) diff --git a/doc/examples/action.py b/doc/examples/action.py new file mode 100644 index 0000000..59e050b --- /dev/null +++ b/doc/examples/action.py @@ -0,0 +1,116 @@ +#!/usr/bin/python3 +# +# LOW LEVEL example how to deal with the depcache +# +# you probably do not want to use this low level code and use +# the high level "apt" interface instead that can do all this +# but with a nicer API + +import apt_pkg +from progress import TextFetchProgress + +from apt.progress.text import OpProgress + +# init +apt_pkg.init() + +progress = OpProgress() +cache = apt_pkg.Cache(progress) +print("Available packages: %s " % cache.package_count) + +print("Fetching") +progress = TextFetchProgress() +source = apt_pkg.SourceList() +cache.update(progress, source) + +iter = cache["base-config"] +print("example package iter: %s" % iter) + +# get depcache +print("\n\n depcache") +depcache = apt_pkg.DepCache(cache) +depcache.read_pinfile() +print("got a depcache: %s " % depcache) +print("Marked for install: %s " % depcache.inst_count) + +print("\n\n Reinit") +depcache.init(progress) + +# sys.exit() + +# get a canidate version +ver = depcache.get_candidate_ver(iter) +print("Candidate version: %s " % ver) + +print("\n\nQuerry interface") +print(f"{iter.name}.is_upgradable(): {depcache.is_upgradable(iter)}") + +print("\nMarking interface") +print("Marking '%s' for install" % iter.name) +depcache.mark_install(iter) +print("Install count: %s " % depcache.inst_count) +print(f"{iter.name}.marked_install(): {depcache.marked_install(iter)}") +print(f"{iter.name}.marked_upgrade(): {depcache.marked_upgrade(iter)}") +print(f"{iter.name}.marked_delete(): {depcache.marked_delete(iter)}") + +print("Marking %s for delete" % iter.name) +depcache.mark_delete(iter) +print("del_count: %s " % depcache.del_count) +print(f"{iter.name}.marked_delete(): {depcache.marked_delete(iter)}") + +iter = cache["apt"] +print("\nMarking '%s' for install" % iter.name) +depcache.mark_install(iter) +print("Install count: %s " % depcache.inst_count) +print(f"{iter.name}.marked_install(): {depcache.marked_install(iter)}") +print(f"{iter.name}.marked_upgrade(): {depcache.marked_upgrade(iter)}") +print(f"{iter.name}.marked_delete(): {depcache.marked_delete(iter)}") + +print("Marking %s for keep" % iter.name) +depcache.mark_keep(iter) +print("Install: %s " % depcache.inst_count) + +iter = cache["python-apt"] +print("\nMarking '%s' for install" % iter.name) +depcache.mark_install(iter) +print("Install: %s " % depcache.inst_count) +print("Broken count: %s" % depcache.broken_count) +print("fix_broken() ") +depcache.fix_broken() +print("Broken count: %s" % depcache.broken_count) + +print("\nPerforming upgrade") +depcache.upgrade() +print("Keep: %s " % depcache.keep_count) +print("Install: %s " % depcache.inst_count) +print("Delete: %s " % depcache.del_count) +print("usr_size: %s " % apt_pkg.size_to_str(depcache.usr_size)) +print("deb_size: %s " % apt_pkg.size_to_str(depcache.deb_size)) + +for pkg in cache.packages: + if ( + pkg.current_ver is not None + and not depcache.marked_install(pkg) + and depcache.is_upgradable(pkg) + ): + print("upgrade didn't upgrade (kept): %s" % pkg.name) + +print("\nPerforming Distupgrade") +depcache.upgrade(True) +print("Keep: %s " % depcache.keep_count) +print("Install: %s " % depcache.inst_count) +print("Delete: %s " % depcache.del_count) +print("usr_size: %s " % apt_pkg.size_to_str(depcache.usr_size)) +print("deb_size: %s " % apt_pkg.size_to_str(depcache.deb_size)) + +# overview about what would happen +for pkg in cache.packages: + if depcache.marked_install(pkg): + if pkg.current_ver is not None: + print("Marked upgrade: %s " % pkg.name) + else: + print("Marked install: %s" % pkg.name) + elif depcache.marked_delete(pkg): + print("Marked delete: %s" % pkg.name) + elif depcache.marked_keep(pkg): + print("Marked keep: %s" % pkg.name) diff --git a/doc/examples/all_deps.py b/doc/examples/all_deps.py new file mode 100644 index 0000000..df8610a --- /dev/null +++ b/doc/examples/all_deps.py @@ -0,0 +1,37 @@ +#!/usr/bin/python3 +import sys + +import apt + + +def dependencies(cache, pkg, deps, key="Depends"): + # print "pkg: %s (%s)" % (pkg.name, deps) + candver = cache._depcache.get_candidate_ver(pkg._pkg) + if candver is None: + return deps + dependslist = candver.depends_list + if key in dependslist: + for depVerList in dependslist[key]: + for dep in depVerList: + if dep.target_pkg.name in cache: + if ( + pkg.name != dep.target_pkg.name + and dep.target_pkg.name not in deps + ): + deps.add(dep.target_pkg.name) + dependencies(cache, cache[dep.target_pkg.name], deps, key) + return deps + + +pkgname = sys.argv[1] +c = apt.Cache() +pkg = c[pkgname] + +deps = set() + +deps = dependencies(c, pkg, deps, "Depends") +print(" ".join(deps)) + +preDeps = set() +preDeps = dependencies(c, pkg, preDeps, "PreDepends") +print(" ".join(preDeps)) diff --git a/doc/examples/architecture.py b/doc/examples/architecture.py new file mode 100644 index 0000000..3972234 --- /dev/null +++ b/doc/examples/architecture.py @@ -0,0 +1,12 @@ +import apt_pkg + + +def main(): + apt_pkg.init_config() + + print("Native architecture:", apt_pkg.config["APT::Architecture"]) + print("All architectures:", apt_pkg.config.value_list("APT::Architectures")) + + +if __name__ == "__main__": + main() diff --git a/doc/examples/build-deps-old.py b/doc/examples/build-deps-old.py new file mode 100755 index 0000000..71a081e --- /dev/null +++ b/doc/examples/build-deps-old.py @@ -0,0 +1,74 @@ +#!/usr/bin/python3 +# this is a example how to access the build dependencies of a package + +import sys + +import apt_pkg + + +def get_source_pkg(pkg, records, depcache): + """get the source package name of a given package""" + version = depcache.get_candidate_ver(pkg) + if not version: + return None + file, index = version.file_list.pop(0) + records.lookup((file, index)) + if records.source_pkg != "": + srcpkg = records.source_pkg + else: + srcpkg = pkg.name + return srcpkg + + +# main +apt_pkg.init() +cache = apt_pkg.Cache() +depcache = apt_pkg.DepCache(cache) +depcache.init() +records = apt_pkg.PackageRecords(cache) +srcrecords = apt_pkg.SourceRecords() + +# base package that we use for build-depends calculation +if len(sys.argv) < 2: + print("need a package name as argument") + sys.exit(1) +try: + pkg = base = cache[sys.argv[1]] +except KeyError: + print("No package %s found" % sys.argv[1]) + sys.exit(1) +all_build_depends = set() + +# get the build depdends for the package itself +srcpkg_name = get_source_pkg(base, records, depcache) +print("srcpkg_name: %s " % srcpkg_name) +if not srcpkg_name: + print("Can't find source package for '%s'" % pkg.mame) +srcrec = srcrecords.lookup(srcpkg_name) +if srcrec: + print("Files:") + print(srcrecords.files) + bd = srcrecords.build_depends + print("build-depends of the package: %s " % bd) + for b in bd: + all_build_depends.add(b[0]) + +# calculate the build depends for all dependencies +depends = depcache.get_candidate_ver(base).depends_list +for dep in depends["Depends"]: # FIXME: do we need to consider PreDepends? + pkg = dep[0].target_pkg + srcpkg_name = get_source_pkg(pkg, records, depcache) + if not srcpkg_name: + print("Can't find source package for '%s'" % pkg.name) + continue + srcrec = srcrecords.lookup(srcpkg_name) + if srcrec: + # print srcrecords.package + # print srcrecords.binaries + bd = srcrecords.build_depends + # print "%s: %s " % (srcpkg_name, bd) + for b in bd: + all_build_depends.add(b[0]) + + +print("\n".join(all_build_depends)) diff --git a/doc/examples/build-deps.py b/doc/examples/build-deps.py new file mode 100755 index 0000000..714d1c4 --- /dev/null +++ b/doc/examples/build-deps.py @@ -0,0 +1,58 @@ +#!/usr/bin/python3 +# this is a example how to access the build dependencies of a package + +import sys + +import apt_pkg + +import apt + +# main +cache = apt.Cache() +srcrecords = apt_pkg.SourceRecords() + +# base package that we use for build-depends calculation +if len(sys.argv) < 2: + print("need a package name as argument") + sys.exit(1) +try: + pkg = base = cache[sys.argv[1]] +except KeyError: + print("No package %s found" % sys.argv[1]) + sys.exit(1) +all_build_depends = set() + +# get the build depdends for the package itself +srcpkg_name = base.candidate.source_name +print("srcpkg_name: %s " % srcpkg_name) +if not srcpkg_name: + print("Can't find source package for '%s'" % pkg.name) +srcrec = srcrecords.lookup(srcpkg_name) +if srcrec: + print("Files:") + print(srcrecords.files) + bd = srcrecords.build_depends + print("build-depends of the package: %s " % bd) + for b in bd: + all_build_depends.add(b[0]) + +# calculate the build depends for all dependencies +depends = base.candidate.dependencies +for or_dep in depends: + for dep in or_dep.or_dependencies: + pkg = cache[dep.name] + srcpkg_name = pkg.candidate.source_name + if not srcpkg_name: + print("Can't find source package for '%s'" % pkg.name) + continue + srcrec = srcrecords.lookup(srcpkg_name) + if srcrec: + # print srcrecords.package + # print srcrecords.binaries + bd = srcrecords.build_depends + # print "%s: %s " % (srcpkg_name, bd) + for b in bd: + all_build_depends.add(b[0]) + + +print("\n".join(all_build_depends)) diff --git a/doc/examples/cdrom.py b/doc/examples/cdrom.py new file mode 100644 index 0000000..ad4d2ba --- /dev/null +++ b/doc/examples/cdrom.py @@ -0,0 +1,24 @@ +#!/usr/bin/python3 +# example how to deal with the depcache + +import sys + +import apt_pkg +from progress import TextCdromProgress + +# init +apt_pkg.init() + +cdrom = apt_pkg.Cdrom() +print(cdrom) + +progress = TextCdromProgress() + +(res, ident) = cdrom.ident(progress) +print(f"ident result is: {res} ({ident}) ") + +apt_pkg.config["APT::CDROM::Rename"] = "True" +cdrom.add(progress) + +print("Exiting") +sys.exit(0) diff --git a/doc/examples/checkstate.py b/doc/examples/checkstate.py new file mode 100755 index 0000000..d4276e8 --- /dev/null +++ b/doc/examples/checkstate.py @@ -0,0 +1,37 @@ +#!/usr/bin/python3 +# +# +# this example is not usefull to find out about updated, upgradable packages +# use the depcache.py example for it (because a pkgPolicy is not used here) +# + +import apt_pkg + +apt_pkg.init() + +cache = apt_pkg.Cache() +packages = cache.packages + +uninstalled, updated, upgradable = {}, {}, {} + +for package in packages: + versions = package.version_list + if not versions: + continue + version = versions[0] + for other_version in versions: + if apt_pkg.version_compare(version.ver_str, other_version.ver_str) < 0: + version = other_version + if package.current_ver: + current = package.current_ver + if apt_pkg.version_compare(current.ver_str, version.ver_str) < 0: + upgradable[package.name] = version + break + else: + updated[package.name] = current + else: + uninstalled[package.name] = version + + +for line in (uninstalled, updated, upgradable): + print(list(line.items())[0]) diff --git a/doc/examples/config.py b/doc/examples/config.py new file mode 100755 index 0000000..fb687e3 --- /dev/null +++ b/doc/examples/config.py @@ -0,0 +1,60 @@ +#!/usr/bin/python3 +# Example demonstrating how to use the configuration/commandline system +# for configuration. +# Some valid command lines.. +# config.py -h --help ; Turn on help +# config.py -no-h --no-help --help=no ; Turn off help +# config.py -qqq -q=3 ; verbosity to 3 +# config.py -c /etc/apt/apt.conf ; include that config file] +# config.py -o help=true ; Turn on help by giving a +# ; config file string +# config.py -no-h -- -help ; Turn off help, specify the file '-help' +# -c and -o are standard APT-program options. + +import posixpath +import sys + +# This shows how to use the system for configuration and option control. +# The other varient is for ISC object config files. See configisc.py. +import apt_pkg + +# Create a new empty Configuration object - there is also the system global +# configuration object apt_pkg.config which is used interally by apt-pkg +# routines to control unusual situations. I recommend using the sytem global +# whenever possible.. +Cnf = apt_pkg.Configuration() + +print("Command line is", sys.argv) + +# Load the default configuration file, init_config() does this better.. +Cnf.set("config-file", "/etc/apt/apt.conf") # or Cnf["config-file"] = ".." +if posixpath.exists(Cnf.find_file("config-file")): + apt_pkg.read_config_file(Cnf, "/etc/apt/apt.conf") + +# Merge the command line arguments into the configuration space +Arguments = [ + ("h", "help", "help"), + ("v", "version", "version"), + ("q", "quiet", "quiet", "IntLevel"), + ("c", "config-file", "", "ConfigFile"), + ("o", "option", "", "ArbItem"), +] +print("FileNames", apt_pkg.parse_commandline(Cnf, Arguments, sys.argv)) + +print("Quiet level selected is", Cnf.find_i("quiet", 0)) + +# Do some stuff with it +if Cnf.find_b("version", 0) == 1: + print("Version selected - 1.1") + +if Cnf.find_b("help", 0) == 1: + print("python-apt", apt_pkg.VERSION, "compiled on", apt_pkg.DATE, apt_pkg.TIME) + print("Hi, I am the help text for this program") + sys.exit(0) + +print("No help for you, try -h") + +# Print the configuration space +print("The Configuration space looks like:") +for item in list(Cnf.keys()): + print(f'{item} "{Cnf[item]}";') diff --git a/doc/examples/configisc.py b/doc/examples/configisc.py new file mode 100755 index 0000000..10700dc --- /dev/null +++ b/doc/examples/configisc.py @@ -0,0 +1,49 @@ +#!/usr/bin/python3 +# Example demonstrating how to use the configuration/commandline system +# for object setup. + +# This parses the given config file in 'ISC' style where the sections +# represent object instances and shows how to iterate over the sections. +# Pass it the sample apt-ftparchive configuration, +# doc/examples/ftp-archive.conf +# or a bind8 config file.. + +import sys + +import apt_pkg + +ConfigFile = apt_pkg.parse_commandline(apt_pkg.config, [], sys.argv) + +if len(ConfigFile) != 1: + print("Must have exactly 1 file name") + sys.exit(0) + +Cnf = apt_pkg.Configuration() +apt_pkg.read_config_file_isc(Cnf, ConfigFile[0]) + +# Print the configuration space +# print "The Configuration space looks like:" +# for item in Cnf.keys(): +# print "%s \"%s\";" % (item, Cnf[item]) + +# bind8 config file.. +if "Zone" in Cnf: + print("Zones: ", Cnf.sub_tree("zone").list()) + for item in Cnf.list("zone"): + SubCnf = Cnf.sub_tree(item) + if SubCnf.find("type") == "slave": + print( + "Masters for {}: {}".format( + SubCnf.my_tag(), SubCnf.value_list("masters") + ) + ) +else: + print("Tree definitions:") + for item in Cnf.list("tree"): + SubCnf = Cnf.sub_tree(item) + # This could use Find which would eliminate the possibility of + # exceptions. + print( + "Subtree %s with sections '%s' and architectures '%s'" + % (SubCnf.my_tag(), SubCnf["Sections"], SubCnf["Architectures"]) + ) diff --git a/doc/examples/deb_inspect.py b/doc/examples/deb_inspect.py new file mode 100755 index 0000000..72050e3 --- /dev/null +++ b/doc/examples/deb_inspect.py @@ -0,0 +1,61 @@ +#!/usr/bin/python3 +# some example for apt_inst + +import os.path +import sys + +import apt_inst +import apt_pkg + + +def Callback(member, data): + """callback for debExtract""" + print( + "'%s','%s',%u,%u,%u,%u,%u,%u,%u" + % ( + member.name, + member.linkname, + member.mode, + member.uid, + member.gid, + member.size, + member.mtime, + member.major, + member.minor, + ) + ) + + +if __name__ == "__main__": + if len(sys.argv) < 2: + print("need filename argumnet") + sys.exit(1) + file = sys.argv[1] + + print("Working on: %s" % file) + print("Displaying data.tar.gz:") + apt_inst.DebFile(open(file)).data.go(Callback) + + print("Now extracting the control file:") + control = apt_inst.DebFile(open(file)).control.extractdata("control") + sections = apt_pkg.TagSection(control) + + print("Maintainer is: ") + print(sections["Maintainer"]) + + print() + print("DependsOn: ") + depends = sections["Depends"] + print(apt_pkg.parse_depends(depends)) + + print("extracting archive") + dir = "/tmp/deb" + os.mkdir(dir) + apt_inst.DebFile(open(file)).data.extractall(dir) + + def visit(arg, dirname, names): + print("%s/" % dirname) + for file in names: + print("\t%s" % file) + + os.path.walk(dir, visit, None) diff --git a/doc/examples/depcache.py b/doc/examples/depcache.py new file mode 100644 index 0000000..f6dff52 --- /dev/null +++ b/doc/examples/depcache.py @@ -0,0 +1,109 @@ +#!/usr/bin/python3 +# example how to deal with the depcache + +import apt_pkg +from progress import TextProgress + +# init +apt_pkg.init() + +progress = TextProgress() +cache = apt_pkg.Cache(progress) +print("Available packages: %s " % cache.package_count) + +iter = cache["base-config"] +print("example package iter: %s" % iter) + +# get depcache +print("\n\n depcache") +depcache = apt_pkg.DepCache(cache) +depcache.read_pinfile() +# init is needed after the creation/pin file reading +depcache.init(progress) +print("got a depcache: %s " % depcache) +print("Marked for install: %s " % depcache.inst_count) + +print("\n\n Reinit") +depcache.init(progress) + +# sys.exit() + + +# get a canidate version +ver = depcache.get_candidate_ver(iter) +print("Candidate version: %s " % ver) + +print("\n\nQuerry interface") +print(f"{iter.name}.is_upgradable(): {depcache.is_upgradable(iter)}") + +print("\nMarking interface") +print("Marking '%s' for install" % iter.name) +depcache.mark_install(iter) +print("Install count: %s " % depcache.inst_count) +print(f"{iter.name}.marked_install(): {depcache.marked_install(iter)}") +print(f"{iter.name}.marked_upgrade(): {depcache.marked_upgrade(iter)}") +print(f"{iter.name}.marked_delete(): {depcache.marked_delete(iter)}") + +print("Marking %s for delete" % iter.name) +depcache.mark_delete(iter) +print("del_count: %s " % depcache.del_count) +print(f"{iter.name}.marked_delete(): {depcache.marked_delete(iter)}") + + +iter = cache["3dchess"] +print("\nMarking '%s' for install" % iter.name) +depcache.mark_install(iter) +print("Install count: %s " % depcache.inst_count) +print(f"{iter.name}.marked_install(): {depcache.marked_install(iter)}") +print(f"{iter.name}.marked_upgrade(): {depcache.marked_upgrade(iter)}") +print(f"{iter.name}.marked_delete(): {depcache.marked_delete(iter)}") + +print("Marking %s for keep" % iter.name) +depcache.mark_keep(iter) +print("Install: %s " % depcache.inst_count) + +iter = cache["synaptic"] +print("\nMarking '%s' for install" % iter.name) +depcache.mark_install(iter) +print("Install: %s " % depcache.inst_count) +print("Broken count: %s" % depcache.broken_count) +print("fix_broken() ") +depcache.fix_broken() +print("Broken count: %s" % depcache.broken_count) + +print("\nPerforming upgrade") +depcache.upgrade() +print("Keep: %s " % depcache.keep_count) +print("Install: %s " % depcache.inst_count) +print("Delete: %s " % depcache.del_count) +print("usr_size: %s " % apt_pkg.size_to_str(depcache.usr_size)) +print("deb_size: %s " % apt_pkg.size_to_str(depcache.deb_size)) + +for pkg in cache.packages: + if ( + pkg.current_ver is not None + and not depcache.marked_install(pkg) + and depcache.is_upgradable(pkg) + ): + print("upgrade didn't upgrade (kept): %s" % pkg.name) + + +print("\nPerforming DistUpgrade") +depcache.upgrade(True) +print("Keep: %s " % depcache.keep_count) +print("Install: %s " % depcache.inst_count) +print("Delete: %s " % depcache.del_count) +print("usr_size: %s " % apt_pkg.size_to_str(depcache.usr_size)) +print("deb_size: %s " % apt_pkg.size_to_str(depcache.deb_size)) + +# overview about what would happen +for pkg in cache.packages: + if depcache.marked_install(pkg): + if pkg.current_ver is not None: + print("Marked upgrade: %s " % pkg.name) + else: + print("Marked install: %s" % pkg.name) + elif depcache.marked_delete(pkg): + print("Marked delete: %s" % pkg.name) + elif depcache.marked_keep(pkg): + print("Marked keep: %s" % pkg.name) diff --git a/doc/examples/dependant-pkgs.py b/doc/examples/dependant-pkgs.py new file mode 100755 index 0000000..e5985b8 --- /dev/null +++ b/doc/examples/dependant-pkgs.py @@ -0,0 +1,38 @@ +#!/usr/bin/python3 + +import sys + +import apt + +pkgs = set() +cache = apt.Cache() +for pkg in cache: + candver = cache._depcache.get_candidate_ver(pkg._pkg) + if candver is None: + continue + dependslist = candver.depends_list + for dep in list(dependslist.keys()): + # get the list of each dependency object + for depVerList in dependslist[dep]: + for z in depVerList: + # get all TargetVersions of + # the dependency object + for tpkg in z.all_targets(): + if sys.argv[1] == tpkg.parent_pkg.name: + pkgs.add(pkg.name) + +main = set() +universe = set() +for pkg in pkgs: + cand = cache[pkg].candidate + if "universe" in cand.section: + universe.add(cand.source_name) + else: + main.add(cand.source_name) + +print("main:") +print("\n".join(sorted(main))) +print() + +print("universe:") +print("\n".join(sorted(universe))) diff --git a/doc/examples/desc.py b/doc/examples/desc.py new file mode 100644 index 0000000..7e8e3e8 --- /dev/null +++ b/doc/examples/desc.py @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import apt_pkg + +apt_pkg.init() + +apt_pkg.config.set("APT::Acquire::Translation", "de") + +cache = apt_pkg.Cache() +depcache = apt_pkg.DepCache(cache) + +pkg = cache["gcc"] +cand = depcache.get_candidate_ver(pkg) +print(cand) + +desc = cand.TranslatedDescription +print(desc) +print(desc.file_list) +(f, index) = desc.file_list.pop(0) + +records = apt_pkg.PackageRecords(cache) +records.lookup((f, index)) +desc = records.long_desc +print(len(desc)) +print(desc) diff --git a/doc/examples/indexfile.py b/doc/examples/indexfile.py new file mode 100644 index 0000000..34ea94e --- /dev/null +++ b/doc/examples/indexfile.py @@ -0,0 +1,22 @@ +#!/usr/bin/python3 + +import apt_pkg + +apt_pkg.init() + +sources = apt_pkg.SourceList() +sources.read_main_list() + +cache = apt_pkg.Cache() +depcache = apt_pkg.DepCache(cache) +pkg = cache["libimlib2"] +cand = depcache.get_candidate_ver(pkg) +for f, i in cand.file_list: + index = sources.find_index(f) + print(index) + if index: + print(index.size) + print(index.is_trusted) + print(index.exists) + print(index.has_packages) + print(index.archive_uri("some/path")) diff --git a/doc/examples/inst.py b/doc/examples/inst.py new file mode 100644 index 0000000..892b43b --- /dev/null +++ b/doc/examples/inst.py @@ -0,0 +1,47 @@ +#!/usr/bin/python3 +# example how to deal with the depcache + +import sys + +import apt +from apt.progress import InstallProgress + + +class TextInstallProgress(InstallProgress): + def __init__(self): + apt.progress.InstallProgress.__init__(self) + self.last = 0.0 + + def updateInterface(self): + InstallProgress.updateInterface(self) + if self.last >= self.percent: + return + sys.stdout.write(f"\r[{self.percent}] {self.status}\n") + sys.stdout.flush() + self.last = self.percent + + def conffile(self, current, new): + print(f"conffile prompt: {current} {new}") + + def error(self, errorstr): + print("got dpkg error: '%s'" % errorstr) + + +cache = apt.Cache(apt.progress.OpTextProgress()) + +fprogress = apt.progress.TextFetchProgress() +iprogress = TextInstallProgress() + +pkg = cache["3dchess"] + +# install or remove, the importend thing is to keep us busy :) +if pkg.is_installed: + print("Going to delete %s" % pkg.name) + pkg.mark_delete() +else: + print("Going to install %s" % pkg.name) + pkg.mark_install() +res = cache.commit(fprogress, iprogress) +print(res) + +sys.exit(0) diff --git a/doc/examples/metaindex.py b/doc/examples/metaindex.py new file mode 100644 index 0000000..2497e65 --- /dev/null +++ b/doc/examples/metaindex.py @@ -0,0 +1,16 @@ +#!/usr/bin/python3 + +import apt_pkg + +apt_pkg.init() + +sources = apt_pkg.SourceList() +sources.read_main_list() + + +for metaindex in sources.list: + print(metaindex) + print("uri: ", metaindex.uri) + print("dist: ", metaindex.dist) + print("index_files: ", "\n".join([str(i) for i in metaindex.index_files])) + print() diff --git a/doc/examples/print_uris.py b/doc/examples/print_uris.py new file mode 100755 index 0000000..1b59e00 --- /dev/null +++ b/doc/examples/print_uris.py @@ -0,0 +1,10 @@ +#!/usr/bin/python3 +# +# a example that prints the URIs of all upgradable packages +# + +import apt + +for pkg in apt.Cache(): + if pkg.is_upgradable: + print(pkg.candidate.uri) diff --git a/doc/examples/progress.py b/doc/examples/progress.py new file mode 100644 index 0000000..680a64d --- /dev/null +++ b/doc/examples/progress.py @@ -0,0 +1,118 @@ +#!/usr/bin/python3 + +import sys +import time + +import apt_pkg + +import apt +import apt.progress.base + + +class TextProgress(apt.progress.base.OpProgress): + def __init__(self): + self.last = 0.0 + + def update(self, percent): + if (self.last + 1.0) <= percent: + sys.stdout.write("\rProgress: %i.2 " % (percent)) + self.last = percent + if percent >= 100: + self.last = 0.0 + + def done(self): + self.last = 0.0 + print("\rDone ") + + +class TextFetchProgress(apt.progress.base.AcquireProgress): + def __init__(self): + pass + + def start(self): + pass + + def stop(self): + pass + + def fail(self, item): + print("fail", item) + + def fetch(self, item): + print("fetch", item) + + def ims_hit(self, item): + print("ims_hit", item) + + def pulse(self, owner): + print( + "pulse: CPS: %s/s; Bytes: %s/%s; Item: %s/%s" + % ( + apt_pkg.size_to_str(self.current_cps), + apt_pkg.size_to_str(self.current_bytes), + apt_pkg.size_to_str(self.total_bytes), + self.current_items, + self.total_items, + ) + ) + return True + + def media_change(self, medium, drive): + print(f"Please insert medium {medium} in drive {drive}") + sys.stdin.readline() + # return False + + +class TextInstallProgress(apt.progress.base.InstallProgress): + def __init__(self): + apt.progress.base.InstallProgress.__init__(self) + + def start_update(self): + print("start_update") + + def finish_update(self): + print("finish_update") + + def status_change(self, pkg, percent, status): + print(f"[{percent}] {pkg}: {status}") + + def update_interface(self): + apt.progress.base.InstallProgress.update_interface(self) + # usefull to e.g. redraw a GUI + time.sleep(0.1) + + +class TextCdromProgress(apt.progress.base.CdromProgress): + def __init__(self): + pass + + # update is called regularly so that the gui can be redrawn + + def update(self, text, step): + # check if we actually have some text to display + if text != "": + print(f"Update: {text.strip()} {step}") + + def ask_cdrom_name(self): + sys.stdout.write("Please enter cd-name: ") + cd_name = sys.stdin.readline() + return (True, cd_name.strip()) + + def change_cdrom(self): + print("Please insert cdrom and press ") + answer = sys.stdin.readline() + print(answer) + return True + + +if __name__ == "__main__": + c = apt.Cache() + pkg = c["3dchess"] + if pkg.is_installed: + pkg.mark_delete() + else: + pkg.mark_install() + + res = c.commit(TextFetchProgress(), TextInstallProgress()) + + print(res) diff --git a/doc/examples/recommends.py b/doc/examples/recommends.py new file mode 100755 index 0000000..8539cd5 --- /dev/null +++ b/doc/examples/recommends.py @@ -0,0 +1,37 @@ +#!/usr/bin/python3 + +import apt_pkg + +apt_pkg.init() + +cache = apt_pkg.Cache() + + +class Wanted: + def __init__(self, name): + self.name = name + self.recommended = [] + self.suggested = [] + + +wanted = {} + +for package in cache.packages: + current = package.current_ver + if not current: + continue + depends = current.depends_list + for key, attr in (("Suggests", "suggested"), ("Recommends", "recommended")): + list = depends.get(key, []) + for dependency in list: + name = dependency[0].target_pkg.name + dep = cache[name] + if dep.current_ver: + continue + getattr(wanted.setdefault(name, Wanted(name)), attr).append(package.name) + +ks = list(wanted.keys()) +ks.sort() + +for want in ks: + print(want, wanted[want].recommended, wanted[want].suggested) diff --git a/doc/examples/records.py b/doc/examples/records.py new file mode 100755 index 0000000..b88ed75 --- /dev/null +++ b/doc/examples/records.py @@ -0,0 +1,16 @@ +#!/usr/bin/python3 + +import apt + +cache = apt.Cache() + +for pkg in cache: + if not pkg.candidate.record: + continue + if "Task" in pkg.candidate.record: + print( + "Pkg {} is part of '{}'".format( + pkg.name, pkg.candidate.record["Task"].split() + ) + ) + # print pkg.candidateRecord diff --git a/doc/examples/sources.py b/doc/examples/sources.py new file mode 100644 index 0000000..b467b7d --- /dev/null +++ b/doc/examples/sources.py @@ -0,0 +1,21 @@ +#!/usr/bin/python3 + +import apt_pkg + +apt_pkg.init() + +# cache = apt_pkg.Cache() +# sources = apt_pkg.SourceRecords(cache) + +sources = apt_pkg.SourceRecords() +sources.restart() +while sources.lookup("hello"): + print( + sources.package, + sources.version, + sources.maintainer, + sources.section, + repr(sources.binaries), + ) + print(sources.files) + print(sources.index.archive_uri(sources.files[0][2])) diff --git a/doc/examples/tagfile.py b/doc/examples/tagfile.py new file mode 100755 index 0000000..beb749b --- /dev/null +++ b/doc/examples/tagfile.py @@ -0,0 +1,8 @@ +#!/usr/bin/python3 +import apt_pkg + +Parse = apt_pkg.TagFile(open("/var/lib/dpkg/status")) + +while Parse.step() == 1: + print(Parse.section.get("Package")) + print(apt_pkg.parse_depends(Parse.section.get("Depends", ""))) diff --git a/doc/examples/update.py b/doc/examples/update.py new file mode 100755 index 0000000..a8d46b6 --- /dev/null +++ b/doc/examples/update.py @@ -0,0 +1,14 @@ +#!/usr/bin/python3 +import os.path + +import apt_pkg + +import apt + +if __name__ == "__main__": + apt_pkg.config.set("APT::Update::Pre-Invoke::", "touch /tmp/update-about-to-run") + apt_pkg.config.set("APT::Update::Post-Invoke::", "touch /tmp/update-was-run") + c = apt.Cache() + res = c.update(apt.progress.TextFetchProgress()) + print("res: ", res) + assert os.path.exists("/tmp/update-about-to-run") diff --git a/doc/examples/versiontest.py b/doc/examples/versiontest.py new file mode 100755 index 0000000..fcc4c25 --- /dev/null +++ b/doc/examples/versiontest.py @@ -0,0 +1,54 @@ +#!/usr/bin/python3 + +# This is a simple clone of tests/versiontest.cc +import re +import sys + +import apt_pkg + +apt_pkg.init_config() +apt_pkg.init_system() + +TestFile = apt_pkg.parse_commandline(apt_pkg.config, [], sys.argv) +if len(TestFile) != 1: + print("Must have exactly 1 file name") + sys.exit(0) + +# Go over the file.. +list = open(TestFile[0]) +CurLine = 0 +while True: + Line = list.readline() + CurLine = CurLine + 1 + if Line == "": + break + Line = Line.strip() + if len(Line) == 0 or Line[0] == "#": + continue + + Split = re.split("[ \n]", Line) + + # Check forward + if apt_pkg.version_compare(Split[0], Split[1]) != int(Split[2]): + print( + "Comparision failed on line %u. '%s' ? '%s' %i != %i" + % ( + CurLine, + Split[0], + Split[1], + apt_pkg.version_compare(Split[0], Split[1]), + int(Split[2]), + ) + ) + # Check reverse + if apt_pkg.version_compare(Split[1], Split[0]) != -1 * int(Split[2]): + print( + "Comparision failed on line %u. '%s' ? '%s' %i != %i" + % ( + CurLine, + Split[1], + Split[0], + apt_pkg.version_compare(Split[1], Split[0]), + -1 * int(Split[2]), + ) + ) diff --git a/doc/source/c++/api.rst b/doc/source/c++/api.rst new file mode 100644 index 0000000..c8e52ab --- /dev/null +++ b/doc/source/c++/api.rst @@ -0,0 +1,858 @@ +Python APT C++ API +================== +The C++ API provides functions to create Python objects from C++ objects and +to retrieve the C++ object stored in the Python object. An object may have +another Python object as its owner and keeps its owner alive for its +lifetime. Some objects require an owner of a specific type, while others +require none. Refer to the sections below for details. + +The C++ API names use the name of the class in apt_pkg and are prefixed with +Py. For each supported class, there is a _Type object, a _Check() function, +a _CheckExact() function, a _FromCpp() and a _ToCpp() function. + +.. versionadded:: 0.7.100 + +Acquire (pkgAcquire) +-------------------- +.. cpp:var:: PyTypeObject PyAcquire_Type + + The type object for :class:`apt_pkg.Acquire` objects. + +.. cpp:function:: int PyAcquire_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Acquire` object, or + a subclass thereof. + +.. cpp:function:: int PyAcquire_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Acquire` object and no + subclass thereof. + +.. cpp:function:: PyObject* PyAcquire_FromCpp(pkgAcquire *acquire, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.Acquire` object from the :cpp:type:`pkgAcquire` + pointer given by the parameter *acquire*. If the parameter *delete* is + true, the object pointed to by *acquire* will be deleted when the refcount + of the return value reaches 0. + +.. cpp:function:: pkgAcquire* PyAcquire_ToCpp(PyObject *acquire) + + Return the :cpp:type:`pkgAcquire` pointer contained in the Python object + *acquire*. + + +AcquireFile (pkgAcqFile) +------------------------ +.. cpp:var:: PyTypeObject PyAcquireFile_Type + + The type object for :class:`apt_pkg.AcquireFile` objects. + +.. cpp:function:: int PyAcquireFile_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.AcquireFile` object, or + a subclass thereof. + +.. cpp:function:: int PyAcquireFile_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.AcquireFile` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyAcquireFile_FromCpp(pkgAcqFile *file, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.AcquireFile` object from the :cpp:type:`pkgAcqFile` + pointer given by the parameter *file*. If the parameter *delete* is + true, the object pointed to by *file* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* should point + to a :class:`apt_pkg.Acquire` object. + +.. cpp:function:: pkgAcqFile* PyAcquireFile_ToCpp(PyObject *acquire) + + Return the :cpp:type:`pkgAcqFile` pointer contained in the Python object + *acquire*. + +AcquireItem (pkgAcquire::Item) +------------------------------ +.. cpp:var:: PyTypeObject PyAcquireItem_Type + + The type object for :class:`apt_pkg.AcquireItem` objects. + +.. cpp:function:: int PyAcquireItem_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.AcquireItem` object, or + a subclass thereof. + +.. cpp:function:: int PyAcquireItem_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.AcquireItem` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyAcquireItem_FromCpp(pkgAcquire::Item *item, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.AcquireItem` object from the :cpp:type:`pkgAcquire::Item` + pointer given by the parameter *item*. If the parameter *delete* is + true, the object pointed to by *item* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* should point + to a :class:`apt_pkg.Acquire` object. + +.. cpp:function:: pkgAcquire::Item* PyAcquireItem_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgAcquire::Item` pointer contained in the Python object + *object*. + +AcquireItemDesc (pkgAcquire::ItemDesc) +-------------------------------------- +.. cpp:var:: PyTypeObject PyAcquireItemDesc_Type + + The type object for :class:`apt_pkg.AcquireItemDesc` objects. + +.. cpp:function:: int PyAcquireItemDesc_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.AcquireItemDesc` object, or + a subclass thereof. + +.. cpp:function:: int PyAcquireItemDesc_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.AcquireItemDesc` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyAcquireItemDesc_FromCpp(pkgAcquire::ItemDesc *desc, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.AcquireItemDesc` object from the :cpp:type:`pkgAcquire::ItemDesc` + pointer given by the parameter *desc*. If the parameter *delete* is + true, the object pointed to by *desc* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* should point + to a :class:`apt_pkg.AcquireItem` object. + +.. cpp:function:: pkgAcquire::ItemDesc* PyAcquireItemDesc_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgAcquire::ItemDesc` pointer contained in the Python object + *object*. + +AcquireWorker (pkgAcquire::Worker) +---------------------------------- +.. cpp:var:: PyTypeObject PyAcquireWorker_Type + + The type object for :class:`apt_pkg.AcquireWorker` objects. + +.. cpp:function:: int PyAcquireWorker_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.AcquireWorker` object, or + a subclass thereof. + +.. cpp:function:: int PyAcquireWorker_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.AcquireWorker` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyAcquireWorker_FromCpp(pkgAcquire::Worker *worker, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.AcquireWorker` object from the :cpp:type:`pkgAcquire::Worker` + pointer given by the parameter *worker*. If the parameter *delete* is + true, the object pointed to by *worker* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* should point + to a :class:`apt_pkg.Acquire` object. + +.. cpp:function:: pkgAcquire::Worker* PyAcquireWorker_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgAcquire::Worker` pointer contained in the Python object + *object*. + +ActionGroup (pkgDepCache::ActionGroup) +-------------------------------------- +.. cpp:var:: PyTypeObject PyActionGroup_Type + + The type object for :class:`apt_pkg.ActionGroup` objects. + +.. cpp:function:: int PyActionGroup_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.ActionGroup` object, or + a subclass thereof. + +.. cpp:function:: int PyActionGroup_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.ActionGroup` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyActionGroup_FromCpp(pkgDepCache::ActionGroup *agroup, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.ActionGroup` object from the :cpp:type:`pkgDepCache::ActionGroup` + pointer given by the parameter *agroup*. If the parameter *delete* is + true, the object pointed to by *agroup* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* should point + to a :class:`apt_pkg.DepCache` object. + +.. cpp:function:: pkgDepCache::ActionGroup* PyActionGroup_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgDepCache::ActionGroup` pointer contained in the + Python object *object*. + +Cache (pkgCache) +------------------------ +.. cpp:var:: PyTypeObject PyCache_Type + + The type object for :class:`apt_pkg.Cache` objects. + +.. cpp:function:: int PyCache_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Cache` object, or + a subclass thereof. + +.. cpp:function:: int PyCache_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Cache` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyCache_FromCpp(pkgCache *cache, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.Cache` object from the :cpp:type:`pkgCache` + pointer given by the parameter *cache*. If the parameter *delete* is + true, the object pointed to by *cache* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* shall point + to a object of the type :cpp:var:`PyCacheFile_Type`. + +.. cpp:function:: pkgCache* PyCache_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgCache` pointer contained in the Python object + *object*. + + +CacheFile (pkgCacheFile) +------------------------ +.. cpp:var:: PyTypeObject PyCacheFile_Type + + The type object for CacheFile. This type is internal and not exported to + Python anywhere. + +.. cpp:function:: int PyCacheFile_Check(PyObject *object) + + Check that the object *object* is of the type :cpp:var:`PyCacheFile_Type` or + a subclass thereof. + +.. cpp:function:: int PyCacheFile_CheckExact(PyObject *object) + + Check that the object *object* is of the type :cpp:var:`PyCacheFile_Type` and + no subclass thereof. + +.. cpp:function:: PyObject* PyCacheFile_FromCpp(pkgCacheFile *file, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.CacheFile` object from the :cpp:type:`pkgCacheFile` + pointer given by the parameter *file* If the parameter *delete* is + true, the object pointed to by *file* will be deleted when the reference + count of the returned object reaches 0. + +.. cpp:function:: pkgCacheFile* PyCacheFile_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgCacheFile` pointer contained in the Python object + *object*. + +Cdrom (pkgCdrom) +------------------------ +.. cpp:var:: PyTypeObject PyCdrom_Type + + The type object for :class:`apt_pkg.Cdrom` objects. + +.. cpp:function:: int PyCdrom_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Cdrom` object, or + a subclass thereof. + +.. cpp:function:: int PyCdrom_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Cdrom` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyCdrom_FromCpp(pkgCdrom &cdrom, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.Cdrom` object from the :cpp:type:`pkgCdrom` + reference given by the parameter *cdrom*. If the parameter *delete* is + true, *cdrom* will be deleted when the reference count of the returned + object reaches 0. + +.. cpp:function:: pkgCdrom& PyCdrom_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgCdrom` reference contained in the Python object + *object*. + +Configuration (Configuration) +------------------------------- +.. cpp:var:: PyTypeObject PyConfiguration_Type + + The type object for :class:`apt_pkg.Configuration` objects. + +.. cpp:function:: int PyConfiguration_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Configuration` object, or + a subclass thereof. + +.. cpp:function:: int PyConfiguration_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Configuration` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyConfiguration_FromCpp(Configuration *cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.Configuration` object from the :cpp:type:`Configuration` + pointer given by the parameter *cpp*. If the parameter *delete* is + true, the object pointed to by *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* may refer to + a parent object (e.g. when exposing a sub tree of a configuration object). + +.. cpp:function:: Configuration* PyConfiguration_ToCpp(PyObject *object) + + Return the :cpp:type:`Configuration` pointer contained in the Python object + *object*. + +DepCache (pkgDepCache) +------------------------ +.. cpp:var:: PyTypeObject PyDepCache_Type + + The type object for :class:`apt_pkg.DepCache` objects. + +.. cpp:function:: int PyDepCache_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.DepCache` object, or + a subclass thereof. + +.. cpp:function:: int PyDepCache_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.DepCache` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyDepCache_FromCpp(pkgDepCache *cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.DepCache` object from the :cpp:type:`pkgDepCache` + pointer given by the parameter *cpp*. If the parameter *delete* is + true, the object pointed to by *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* must be + a PyObject of the type :cpp:var:`PyCache_Type`. + +.. cpp:function:: pkgDepCache* PyDepCache_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgDepCache` pointer contained in the Python object + *object*. + +Dependency (pkgCache::DepIterator) +---------------------------------- +.. cpp:var:: PyTypeObject PyDependency_Type + + The type object for :class:`apt_pkg.Dependency` objects. + +.. cpp:function:: int PyDependency_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Dependency` object, or + a subclass thereof. + +.. cpp:function:: int PyDependency_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Dependency` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyDependency_FromCpp(pkgCache::DepIterator &cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.Dependency` object from the :cpp:type:`pkgCache::DepIterator` + reference given by the parameter *cpp*. If the parameter *delete* is + true, *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* must be + a PyObject of the type :cpp:var:`PyPackage_Type`. + +.. cpp:function:: pkgCache::DepIterator& PyDependency_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgCache::DepIterator` reference contained in the + Python object *object*. + +Description (pkgCache::DescIterator) +------------------------------------ +.. cpp:var:: PyTypeObject PyDescription_Type + + The type object for :class:`apt_pkg.Description` objects. + +.. cpp:function:: int PyDescription_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Description` object, or + a subclass thereof. + +.. cpp:function:: int PyDescription_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Description` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyDescription_FromCpp(pkgCache::DescIterator &cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.Description` object from the :cpp:type:`pkgCache::DescIterator` + reference given by the parameter *cpp*. If the parameter *delete* is + true, *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* must be + a PyObject of the type :cpp:var:`PyPackage_Type`. + +.. cpp:function:: pkgCache::DescIterator& PyDescription_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgCache::DescIterator` reference contained in the + Python object *object*. + + +Group (pkgCache::GrpIterator) +---------------------------------- +.. versionadded:: 0.8.0 + +.. cpp:var:: PyTypeObject PyGroup_Type + + The type object for :class:`apt_pkg.Group` objects. + +.. cpp:function:: int PyGroup_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Group` object, or + a subclass thereof. + +.. cpp:function:: int PyGroup_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Group` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyGroup_FromCpp(pkgCache::GrpIterator &cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.Group` object from the :cpp:type:`pkgCache::GrpIterator` + reference given by the parameter *cpp*. If the parameter *delete* is + true, *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* should be + a PyObject of the type :cpp:var:`PyCache_Type`. + +.. cpp:function:: pkgCache::GrpIterator& PyGroup_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgCache::GrpIterator` reference contained in the + Python object *object*. + +Hashes (Hashes) +---------------------------------- +.. cpp:var:: PyTypeObject PyHashes_Type + + The type object for :class:`apt_pkg.Hashes` objects. + +.. cpp:function:: int PyHashes_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Hashes` object, or + a subclass thereof. + +.. cpp:function:: int PyHashes_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Hashes` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyHashes_FromCpp(Hashes &cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.Hashes` object from the :cpp:type:`Hashes` + reference given by the parameter *cpp*. If the parameter *delete* is + true, *cpp* will be deleted when the reference count of the returned + object reaches 0. + +.. cpp:function:: Hashes& PyHashes_ToCpp(PyObject *object) + + Return the :cpp:type:`Hashes` reference contained in the + Python object *object*. + +HashString (HashString) +------------------------ +.. cpp:var:: PyTypeObject PyHashString_Type + + The type object for :class:`apt_pkg.HashString` objects. + +.. cpp:function:: int PyHashString_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.HashString` object, or + a subclass thereof. + +.. cpp:function:: int PyHashString_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.HashString` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyHashString_FromCpp(HashString *cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.HashString` object from the :cpp:type:`HashString` + pointer given by the parameter *cpp*. If the parameter *delete* is + true, the object pointed to by *cpp* will be deleted when the reference + count of the returned object reaches 0. + +.. cpp:function:: HashString* PyHashString_ToCpp(PyObject *object) + + Return the :cpp:type:`HashString` pointer contained in the Python object + *object*. + +IndexRecords (indexRecords) +---------------------------- +.. cpp:var:: PyTypeObject PyIndexRecords_Type + + The type object for :class:`apt_pkg.IndexRecords` objects. + +.. cpp:function:: int PyIndexRecords_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.IndexRecords` object, or + a subclass thereof. + +.. cpp:function:: int PyIndexRecords_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.IndexRecords` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyIndexRecords_FromCpp(indexRecords *cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.IndexRecords` object from the :cpp:type:`indexRecords` + pointer given by the parameter *cpp*. If the parameter *delete* is + true, the object pointed to by *cpp* will be deleted when the reference + count of the returned object reaches 0. + +.. cpp:function:: indexRecords* PyIndexRecords_ToCpp(PyObject *object) + + Return the :cpp:type:`indexRecords` pointer contained in the Python object + *object*. + + +MetaIndex (metaIndex) +------------------------ +.. cpp:var:: PyTypeObject PyMetaIndex_Type + + The type object for :class:`apt_pkg.MetaIndex` objects. + +.. cpp:function:: int PyMetaIndex_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.MetaIndex` object, or + a subclass thereof. + +.. cpp:function:: int PyMetaIndex_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.MetaIndex` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyMetaIndex_FromCpp(metaIndex *cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.MetaIndex` object from the :cpp:type:`metaIndex` + pointer given by the parameter *cpp*. If the parameter *delete* is + true, the object pointed to by *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* should be + a PyObject of the type :cpp:var:`PySourceList_Type`. + +.. cpp:function:: metaIndex* PyMetaIndex_ToCpp(PyObject *object) + + Return the :cpp:type:`metaIndex` pointer contained in the Python object + *object*. + +Package (pkgCache::PkgIterator) +---------------------------------- +.. cpp:var:: PyTypeObject PyPackage_Type + + The type object for :class:`apt_pkg.Package` objects. + +.. cpp:function:: int PyPackage_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Package` object, or + a subclass thereof. + +.. cpp:function:: int PyPackage_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Package` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyPackage_FromCpp(pkgCache::PkgIterator &cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.Package` object from the :cpp:type:`pkgCache::PkgIterator` + reference given by the parameter *cpp*. If the parameter *delete* is + true, *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* should be + a PyObject of the type :cpp:var:`PyCache_Type`. + +.. cpp:function:: pkgCache::PkgIterator& PyPackage_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgCache::PkgIterator` reference contained in the + Python object *object*. + +PackageFile (pkgCache::PkgFileIterator) +---------------------------------------- +.. cpp:var:: PyTypeObject PyPackageFile_Type + + The type object for :class:`apt_pkg.PackageFile` objects. + +.. cpp:function:: int PyPackageFile_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.PackageFile` object, or + a subclass thereof. + +.. cpp:function:: int PyPackageFile_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.PackageFile` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyPackageFile_FromCpp(pkgCache::PkgFileIterator &cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.PackageFile` object from the :cpp:type:`pkgCache::PkgFileIterator` + reference given by the parameter *cpp*. If the parameter *delete* is + true, *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* should be + a PyObject of the type :cpp:var:`PyCache_Type`. + +.. cpp:function:: pkgCache::PkgFileIterator& PyPackageFile_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgCache::PkgFileIterator` reference contained in the + Python object *object*. + +IndexFile (pkgIndexFile) +-------------------------------------- +.. cpp:var:: PyTypeObject PyIndexFile_Type + + The type object for :class:`apt_pkg.IndexFile` objects. + +.. cpp:function:: int PyIndexFile_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.IndexFile` object, or + a subclass thereof. + +.. cpp:function:: int PyIndexFile_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.IndexFile` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyIndexFile_FromCpp(pkgIndexFile *cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.IndexFile` object from the :cpp:type:`pkgIndexFile` + pointer given by the parameter *cpp*. If the parameter *delete* is + true, the object pointed to by *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* should be + a PyObject of the type :cpp:var:`PyMetaIndex_Type`. + +.. cpp:function:: pkgIndexFile* PyIndexFile_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgIndexFile` pointer contained in the Python object + *object*. + +OrderList (pkgOrderList) +--------------------------- +.. cpp:var:: PyTypeObject PyOrderList_Type + + The type object for :class:`apt_pkg.OrderList` objects. + +.. cpp:function:: int PyOrderList_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.OrderList` object, or + a subclass thereof. + +.. cpp:function:: int PyOrderList_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.OrderList` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyOrderList_FromCpp(pkgOrderList *cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.OrderList` object from the :cpp:type:`pkgOrderList` + pointer given by the parameter *cpp*. If the parameter *delete* is + true, the object pointed to by *cpp* will be deleted when the reference + count of the returned object reaches 0. The owner must be a + :class:`apt_pkg.DepCache` object. + +.. cpp:function:: pkgOrderList* PyOrderList_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgOrderList` pointer contained in the Python object + *object*. + +PackageManager (pkgPackageManager) +---------------------------------- +.. cpp:var:: PyTypeObject PyPackageManager_Type + + The type object for :class:`apt_pkg.PackageManager` objects. + +.. cpp:function:: int PyPackageManager_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.PackageManager` object, or + a subclass thereof. + +.. cpp:function:: int PyPackageManager_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.PackageManager` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyPackageManager_FromCpp(pkgPackageManager *cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.PackageManager` object from the :cpp:type:`pkgPackageManager` + pointer given by the parameter *cpp*. If the parameter *delete* is + true, the object pointed to by *cpp* will be deleted when the reference + count of the returned object reaches 0. + +.. cpp:function:: pkgPackageManager* PyPackageManager_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgPackageManager` pointer contained in the Python object + *object*. + + +Policy (pkgPolicy) +------------------ +.. cpp:var:: PyTypeObject PyPolicy_Type + + The type object for :class:`apt_pkg.Policy` objects. + +.. cpp:function:: int PyPolicy_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Policy` object, or + a subclass thereof. + +.. cpp:function:: int PyPolicy_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Policy` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyPolicy_FromCpp(pkgPolicy *cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.Policy` object from the :cpp:type:`pkgPolicy` + pointer given by the parameter *cpp*. If the parameter *delete* is + true, the object pointed to by *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* must be + a PyObject of the type :cpp:var:`PyCache_Type`. + +.. cpp:function:: pkgPolicy* PyPolicy_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgPolicy` pointer contained in the Python object + *object*. + + +ProblemResolver (pkgProblemResolver) +-------------------------------------- +.. cpp:var:: PyTypeObject PyProblemResolver_Type + + The type object for :class:`apt_pkg.ProblemResolver` objects. + +.. cpp:function:: int PyProblemResolver_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.ProblemResolver` object, or + a subclass thereof. + +.. cpp:function:: int PyProblemResolver_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.ProblemResolver` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyProblemResolver_FromCpp(pkgProblemResolver *cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.ProblemResolver` object from the :cpp:type:`pkgProblemResolver` + pointer given by the parameter *cpp*. If the parameter *delete* is + true, the object pointed to by *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* must be + a PyObject of the type :cpp:var:`PyDepCache_Type`. + +.. cpp:function:: pkgProblemResolver* PyProblemResolver_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgProblemResolver` pointer contained in the Python object + *object*. + + + +SourceList (pkgSourceList) +--------------------------- +.. cpp:var:: PyTypeObject PySourceList_Type + + The type object for :class:`apt_pkg.SourceList` objects. + +.. cpp:function:: int PySourceList_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.SourceList` object, or + a subclass thereof. + +.. cpp:function:: int PySourceList_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.SourceList` object + and no subclass thereof. + +.. cpp:function:: PyObject* PySourceList_FromCpp(pkgSourceList *cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.SourceList` object from the :cpp:type:`pkgSourceList` + pointer given by the parameter *cpp*. If the parameter *delete* is + true, the object pointed to by *cpp* will be deleted when the reference + count of the returned object reaches 0. + +.. cpp:function:: pkgSourceList* PySourceList_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgSourceList` pointer contained in the Python object + *object*. + + +TagFile (pkgTagFile) +---------------------------------- +.. cpp:var:: PyTypeObject PyTagFile_Type + + The type object for :class:`apt_pkg.TagFile` objects. + +.. cpp:function:: int PyTagFile_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.TagFile` object, or + a subclass thereof. + +.. cpp:function:: int PyTagFile_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.TagFile` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyTagFile_FromCpp(pkgTagFile &cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.TagFile` object from the :cpp:type:`pkgTagFile` + reference given by the parameter *cpp*. If the parameter *delete* is + true, *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* may be any + Python object. + +.. cpp:function:: pkgTagFile& PyTagFile_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgTagFile` reference contained in the + Python object *object*. + +TagSection (pkgTagSection) +---------------------------------- +.. cpp:var:: PyTypeObject PyTagSection_Type + + The type object for :class:`apt_pkg.TagSection` objects. + +.. cpp:function:: int PyTagSection_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.TagSection` object, or + a subclass thereof. + +.. cpp:function:: int PyTagSection_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.TagSection` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyTagSection_FromCpp(pkgTagSection &cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.TagSection` object from the :cpp:type:`pkgTagSection` + reference given by the parameter *cpp*. If the parameter *delete* is + true, *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* may be + a PyObject of the type :cpp:var:`PyTagFile_Type`. + +.. cpp:function:: pkgTagSection& PyTagSection_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgTagSection` reference contained in the + Python object *object*. + +Version (pkgCache::VerIterator) +---------------------------------- +.. cpp:var:: PyTypeObject PyVersion_Type + + The type object for :class:`apt_pkg.Version` objects. + +.. cpp:function:: int PyVersion_Check(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Version` object, or + a subclass thereof. + +.. cpp:function:: int PyVersion_CheckExact(PyObject *object) + + Check that the object *object* is an :class:`apt_pkg.Version` object + and no subclass thereof. + +.. cpp:function:: PyObject* PyVersion_FromCpp(pkgCache::VerIterator &cpp, bool delete, PyObject *owner) + + Create a new :class:`apt_pkg.Version` object from the :cpp:type:`pkgCache::VerIterator` + reference given by the parameter *cpp*. If the parameter *delete* is + true, *cpp* will be deleted when the reference + count of the returned object reaches 0. The parameter *owner* must be + a PyObject of the type :cpp:var:`PyPackage_Type`. + +.. cpp:function:: pkgCache::VerIterator& PyVersion_ToCpp(PyObject *object) + + Return the :cpp:type:`pkgCache::VerIterator` reference contained in the + Python object *object*. diff --git a/doc/source/c++/embedding.rst b/doc/source/c++/embedding.rst new file mode 100644 index 0000000..cb175f8 --- /dev/null +++ b/doc/source/c++/embedding.rst @@ -0,0 +1,34 @@ +.. highlight:: c++ + +Embedding Python APT +==================== +This is a very basic tutorial for working with the C++ bindings. + +Basics +------- +To use the python-apt C++ bindings, first include the +``python-apt/python-apt.h`` header:: + + #include + +Now, the module needs to be initialized. This is done by calling the function +:c:func:`import_apt_pkg`. This function returns 0 on success and a negative +value in case of failure:: + + if (import_apt_pkg() < 0) + return; + +Longer example +-------------- +The following code will create a standalone application which provides a +module ``client`` with the attribute ``hash`` which stores an object of the +type :class:`apt_pkg.HashString`: + +.. literalinclude:: ../../client-example.cc + + +.. highlight:: sh + +If this file were called client-example.cc, you could compile it using:: + + g++ -lapt-pkg -lpython2.5 -I/usr/include/python2.5 -o client client-example.cc diff --git a/doc/source/c++/index.rst b/doc/source/c++/index.rst new file mode 100644 index 0000000..8f598f3 --- /dev/null +++ b/doc/source/c++/index.rst @@ -0,0 +1,8 @@ +Python APT and C++ +================== + +.. toctree:: + :maxdepth: 1 + + api + embedding diff --git a/doc/source/conf.py b/doc/source/conf.py new file mode 100644 index 0000000..079cc50 --- /dev/null +++ b/doc/source/conf.py @@ -0,0 +1,245 @@ +# +# python-apt documentation build configuration file, created by +# sphinx-quickstart on Wed Jan 7 17:04:36 2009. +# +# This file is execfile()d with the current directory set to its containing +# dir. +# +# The contents of this file are pickled, so don't put values in the namespace +# that aren't pickleable (module imports are okay, they're removed +# automatically). +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. +import glob +import os +import sys + +# Find the path to the built apt_pkg and apt_inst extensions +if os.path.exists("../../build"): + version = ".".join(str(x) for x in sys.version_info[:2]) + for apt_pkg_path in glob.glob("../../build/lib*%s/*.so" % version): + sys.path.insert(0, os.path.abspath(os.path.dirname(apt_pkg_path))) + try: + import apt_pkg + + apt_pkg # pyflakes + except ImportError as exc: + # Not the correct version + sys.stderr.write("W: Ignoring error %s\n" % exc) + sys.path.pop(0) + else: + sys.stdout.write("I: Found apt_pkg.so in %s\n" % sys.path[0]) + break + + +# General configuration +# --------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.doctest", + "sphinx.ext.intersphinx", + "sphinx.ext.todo", +] +intersphinx_mapping = {"http://docs.python.org/": None} + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["templates"] + +# The suffix of source filenames. +source_suffix = ".rst" + +# The encoding of source files. +# source_encoding = 'utf-8' + +# The master toctree document. +master_doc = "contents" + +# General information about the project. +project = "python-apt" +copyright = "2009-2010, Julian Andres Klode " + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# + +try: + release = os.environ["DEBVER"] +except KeyError: + from subprocess import PIPE, Popen + + p1 = Popen(["dpkg-parsechangelog", "-l../../debian/changelog"], stdout=PIPE) + p2 = Popen(["sed", "-n", "s/^Version: //p"], stdin=p1.stdout, stdout=PIPE) + release = p2.communicate()[0].decode("utf-8") + + +# Handle the alpha release scheme +release_raw = "0" +for c in release.split("~")[0].split(".")[2]: + if not c.isdigit(): + break + release_raw += c + +if int(release_raw) >= 90: + version_s = release.split("~")[0].split(".")[:3] + # Set the version to 0.X.100 if the release is 0.X.9Y (0.7.90 => 0.7.100) + # Use + # version_s[1] = str(int(version_s[1]) + 1) + # version_s[2] = "0" + # if the version of a 0.X.9Y release should be 0.X+1.0 (0.7.90=>0.8) + version_s[2] = "100" + version = ".".join(version_s) + del version_s +else: + version = ".".join(release.split("~")[0].split(".")[:2]) +del release_raw + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +# language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +# today = '' +# Else, today_fmt is used as the format for a strftime call. +# today_fmt = '%B %d, %Y' + +# List of documents that shouldn't be included in the build. +# unused_docs = [] + +# List of directories, relative to source directory, that shouldn't be searched +# for source files. +exclude_trees = [] + +# The reST default role (used for this markup: `text`) for all documents. +# default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +# add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +# add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +# show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = "sphinx" + + +# Options for HTML output +# ----------------------- + +# The style sheet to use for HTML and HTML Help pages. A file of that name +# must exist either in Sphinx' static/ path, or in one of the custom paths +# given in html_static_path. +# html_style = 'default.css' + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +# html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +# html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +# html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +# html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = [".static"] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +html_last_updated_fmt = None + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +# html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +# html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +html_additional_pages = {"index": "indexcontent.html"} + +# If false, no module index is generated. +# html_use_modindex = True + +# If false, no index is generated. +# html_use_index = True + +# If true, the index is split into individual pages for each letter. +# html_split_index = False + +# If true, the reST sources are included in the HTML build as _sources/. +# html_copy_source = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +# html_use_opensearch = '' + +# If nonempty, this is the file name suffix for HTML files (e.g. ".xhtml"). +# html_file_suffix = '' + +# Output file base name for HTML help builder. +htmlhelp_basename = "python-aptdoc" + + +# Options for LaTeX output +# ------------------------ + +# The paper size ('letter' or 'a4'). +# latex_paper_size = 'letter' + +# The font size ('10pt', '11pt' or '12pt'). +# latex_font_size = '10pt' + +# Grouping the document tree into LaTeX files. List of tuples +# (source index, target name, title, author, document class [howto/manual]). +latex_documents = [ + ( + "contents", + "python-apt.tex", + "python-apt Documentation", + "Julian Andres Klode ", + "manual", + ), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +# latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +# latex_use_parts = False + +# Additional stuff for the LaTeX preamble. +# latex_preamble = '' + +# Documents to append as an appendix to all manuals. +# latex_appendices = [] + +# If false, no module index is generated. +# latex_use_modindex = True + +todo_include_todos = True diff --git a/doc/source/contents.rst b/doc/source/contents.rst new file mode 100644 index 0000000..6c4e161 --- /dev/null +++ b/doc/source/contents.rst @@ -0,0 +1,19 @@ +Python APT Documentation contents +====================================== + +Contents: + +.. toctree:: + + whatsnew/index + library/index + tutorials/index + c++/index + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`search` diff --git a/doc/source/examples/apt-cdrom.py b/doc/source/examples/apt-cdrom.py new file mode 100644 index 0000000..13bfb97 --- /dev/null +++ b/doc/source/examples/apt-cdrom.py @@ -0,0 +1,79 @@ +#!/usr/bin/python3 +import sys + +import apt_pkg + +import apt + + +def show_help(): + print(f"apt {apt_pkg.VERSION} compiled on {apt_pkg.DATE} {apt_pkg.TIME}") + if apt_pkg.config.find_b("version"): + return 0 + + # Copied from apt-cdrom + print( + "Usage: apt-cdrom [options] command\n" + "\n" + "apt-cdrom is a tool to add CDROM's to APT's source list. The\n" + "CDROM mount point and device information is taken from apt.conf\n" + "and /etc/fstab.\n" + "\n" + "Commands:\n" + " add - Add a CDROM\n" + " ident - Report the identity of a CDROM\n" + "\n" + "Options:\n" + " -h This help text\n" + " -d CD-ROM mount point\n" + " -r Rename a recognized CD-ROM\n" + " -m No mounting\n" + " -f Fast mode, don't check package files\n" + " -a Thorough scan mode\n" + " -c=? Read this configuration file\n" + " -o=? Set an arbitrary configuration option, eg -o " + "dir::cache=/tmp\n" + "See fstab(5)" + ) + return 0 + + +def main(args): + arguments = apt_pkg.parse_commandline( + apt_pkg.config, + [ + ("h", "help", "help"), + ("v", "version", "version"), + ("d", "cdrom", "Acquire::cdrom::mount", "HasArg"), + ("r", "rename", "APT::CDROM::Rename"), + ("m", "no-mount", "APT::CDROM::NoMount"), + ("f", "fast", "APT::CDROM::Fast"), + ("n", "just-print", "APT::CDROM::NoAct"), + ("n", "recon", "APT::CDROM::NoAct"), + ("n", "no-act", "APT::CDROM::NoAct"), + ("a", "thorough", "APT::CDROM::Thorough"), + ("c", "config-file", "", "ConfigFile"), + ("o", "option", "", "ArbItem"), + ], + args, + ) + + if apt_pkg.config.find_b("help") or apt_pkg.config.find_b("version"): + return show_help() + + progress = apt.progress.text.CdromProgress() + cdrom = apt_pkg.Cdrom() + + if not arguments: + return show_help() + elif arguments[0] == "add": + cdrom.add(progress) + elif arguments[0] == "ident": + cdrom.ident(progress) + else: + sys.stderr.write("E: Invalid operation %s\n" % arguments[0]) + return 1 + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/doc/source/examples/cache-packages.py b/doc/source/examples/cache-packages.py new file mode 100755 index 0000000..14ba85a --- /dev/null +++ b/doc/source/examples/cache-packages.py @@ -0,0 +1,23 @@ +#!/usr/bin/python3 +"""Example for packages. Print all essential and important packages""" + +import apt_pkg + + +def main(): + """Main.""" + apt_pkg.init_config() + apt_pkg.init_system() + cache = apt_pkg.Cache() + print("Essential packages:") + for pkg in cache.packages: + if pkg.essential: + print(" ", pkg.name) + print("Important packages:") + for pkg in cache.packages: + if pkg.important: + print(" ", pkg.name) + + +if __name__ == "__main__": + main() diff --git a/doc/source/examples/cache-pkgfile.py b/doc/source/examples/cache-pkgfile.py new file mode 100755 index 0000000..4e94a7a --- /dev/null +++ b/doc/source/examples/cache-pkgfile.py @@ -0,0 +1,30 @@ +#!/usr/bin/python3 +import apt_pkg + + +def main(): + """Example for PackageFile()""" + apt_pkg.init() + cache = apt_pkg.Cache() + for pkgfile in cache.file_list: + print("Package-File:", pkgfile.filename) + print("Index-Type:", pkgfile.index_type) # 'Debian Package Index' + if pkgfile.not_source: + print("Source: None") + else: + if pkgfile.site: + # There is a source, and a site, print the site + print("Source:", pkgfile.site) + else: + # It seems to be a local repository + print("Source: Local package file") + if pkgfile.not_automatic: + # The system won't be updated automatically (eg. experimental) + print("Automatic: No") + else: + print("Automatic: Yes") + print() + + +if __name__ == "__main__": + main() diff --git a/doc/source/examples/dpkg-contents.py b/doc/source/examples/dpkg-contents.py new file mode 100755 index 0000000..e6ff620 --- /dev/null +++ b/doc/source/examples/dpkg-contents.py @@ -0,0 +1,68 @@ +#!/usr/bin/python3 +"""Emulate dpkg --contents""" + +import grp +import pwd +import stat +import sys +import time + +import apt_inst + + +def format_mode(member): + """Return the symbolic mode""" + mode = member.mode + if member.isdir(): + s_mode = "d" + elif member.islnk(): + s_mode = "h" + else: + s_mode = "-" + s_mode += (mode & stat.S_IRUSR) and "r" or "-" + s_mode += (mode & stat.S_IWUSR) and "w" or "-" + s_mode += ( + (mode & stat.S_IXUSR) + and (mode & stat.S_ISUID and "s" or "x") + or (mode & stat.S_ISUID and "S" or "-") + ) + s_mode += (mode & stat.S_IRGRP) and "r" or "-" + s_mode += (mode & stat.S_IWGRP) and "w" or "-" + s_mode += ( + (mode & stat.S_IXGRP) + and (mode & stat.S_ISGID and "s" or "x") + or (mode & stat.S_ISGID and "S" or "-") + ) + s_mode += (mode & stat.S_IROTH) and "r" or "-" + s_mode += (mode & stat.S_IWOTH) and "w" or "-" + s_mode += (mode & stat.S_IXOTH) and "x" or "-" + return s_mode + + +def callback(member, data): + """callback for deb_extract""" + s_mode = format_mode(member) + s_owner = f"{pwd.getpwuid(member.uid)[0]}/{grp.getgrgid(member.gid)[0]}" + s_size = "%9d" % member.size + s_time = time.strftime("%Y-%m-%d %H:%M", time.localtime(member.mtime)) + s_name = member.name if member.name.startswith(".") else ("./" + member.name) + if member.islnk(): + s_name += " link to %s" % member.linkname + print(s_mode, s_owner, s_size, s_time, s_name) + + +def main(): + """Main function""" + if len(sys.argv) < 2: + print("need filename argumnet", file=sys.stderr) + sys.exit(1) + + fobj = open(sys.argv[1]) + try: + apt_inst.DebFile(fobj).data.go(callback) + finally: + fobj.close() + + +if __name__ == "__main__": + main() diff --git a/doc/source/examples/dpkg-extract.py b/doc/source/examples/dpkg-extract.py new file mode 100755 index 0000000..02a9fdd --- /dev/null +++ b/doc/source/examples/dpkg-extract.py @@ -0,0 +1,27 @@ +#!/usr/bin/python3 +"""Emulate dpkg --extract package.deb outdir""" + +import os +import sys + +import apt_inst + + +def main(): + """Main function.""" + if len(sys.argv) < 3: + print("Usage: %s package.deb outdir\n" % (__file__), file=sys.stderr) + sys.exit(1) + if not os.path.exists(sys.argv[2]): + print("The directory %s does not exist\n" % (sys.argv[2]), file=sys.stderr) + sys.exit(1) + + fobj = open(sys.argv[1]) + try: + apt_inst.DebFile(fobj).data.extractall(sys.argv[2]) + finally: + fobj.close() + + +if __name__ == "__main__": + main() diff --git a/doc/source/examples/dpkg-info.py b/doc/source/examples/dpkg-info.py new file mode 100755 index 0000000..833c4ed --- /dev/null +++ b/doc/source/examples/dpkg-info.py @@ -0,0 +1,22 @@ +#!/usr/bin/python3 +"""Emulate dpkg --info package.deb control-file""" + +import sys + +from apt_inst import DebFile + + +def main(): + """Main function.""" + if len(sys.argv) < 3: + print("Usage: tool file.deb control-file\n", file=sys.stderr) + sys.exit(0) + fobj = open(sys.argv[1]) + try: + print(DebFile(fobj).control.extractdata(sys.argv[2])) + finally: + fobj.close() + + +if __name__ == "__main__": + main() diff --git a/doc/source/examples/missing-deps.py b/doc/source/examples/missing-deps.py new file mode 100755 index 0000000..c3c56b8 --- /dev/null +++ b/doc/source/examples/missing-deps.py @@ -0,0 +1,59 @@ +#!/usr/bin/python3 +"""Check the archive for missing dependencies""" +import apt_pkg + + +def fmt_dep(dep): + """Format a Dependency object [of apt_pkg] as a string.""" + ret = dep.target_pkg.name + if dep.target_ver: + ret += f" ({dep.comp_type} {dep.target_ver})" + return ret + + +def check_version(pkgver): + """Check the version of the package""" + missing = [] + + for or_group in pkgver.depends_list.get( + "Pre-Depends", [] + ) + pkgver.depends_list.get("Depends", []): + if not any(dep.all_targets() for dep in or_group): + # If none of the or-choices can be satisfied, add it to missing + missing.append(or_group) + + if missing: + print("Package:", pkgver.parent_pkg.name) + print("Version:", pkgver.ver_str) + print("Missing:") + print( + ", ".join(" | ".join(fmt_dep(dep) for dep in or_group)) + for or_group in missing + ) + print() + + +def main(): + """The main function.""" + apt_pkg.init_config() + apt_pkg.init_system() + + cache = apt_pkg.Cache() + + for pkg in sorted(cache.packages, key=lambda pkg: pkg.name): + # pkg is from a list of packages, sorted by name. + for version in pkg.version_list: + # Check every version + for pfile, _ in version.file_list: + if ( + pfile.origin == "Debian" + and pfile.component == "main" + and pfile.archive == "unstable" + ): + # We only want packages from Debian unstable main. + check_version(version) + break + + +if __name__ == "__main__": + main() diff --git a/doc/source/examples/update-print-uris.py b/doc/source/examples/update-print-uris.py new file mode 100755 index 0000000..02981f8 --- /dev/null +++ b/doc/source/examples/update-print-uris.py @@ -0,0 +1,24 @@ +#!/usr/bin/python3 +"""Print out the URIs of all indexes files. + +This behaves somewhat like apt-get --print-uris update.""" +import apt_pkg + + +def main(): + apt_pkg.init_config() + apt_pkg.init_system() + acquire = apt_pkg.Acquire() + slist = apt_pkg.SourceList() + # Read the list + slist.read_main_list() + # Add all indexes to the fetcher. + slist.get_indexes(acquire, True) + + # Now print the URI of every item. + for item in acquire.items: + print(item.desc_uri) + + +if __name__ == "__main__": + main() diff --git a/doc/source/library/apt.cache.rst b/doc/source/library/apt.cache.rst new file mode 100644 index 0000000..f85deb2 --- /dev/null +++ b/doc/source/library/apt.cache.rst @@ -0,0 +1,83 @@ +:mod:`apt.cache` --- The Cache class +===================================== +.. automodule:: apt.cache + +The Cache class +--------------- + +.. autoclass:: Cache + :members: + :undoc-members: + + .. describe:: cache[pkgname] + + Return a :class:`Package()` for the package with the name *pkgname*. + +Example +^^^^^^^ + +The following example shows how to load the cache, update it, and upgrade +all the packages on the system:: + + import apt + import apt.progress + + # First of all, open the cache + cache = apt.Cache() + # Now, lets update the package list + cache.update() + # We need to re-open the cache because it needs to read the package list + cache.open(None) + # Now we can do the same as 'apt-get upgrade' does + cache.upgrade() + # or we can play 'apt-get dist-upgrade' + cache.upgrade(True) + # Q: Why does nothing happen? + # A: You forgot to call commit()! + cache.commit(apt.progress.TextFetchProgress(), + apt.progress.InstallProgress()) + + + +Working with Filters +-------------------- +.. autoclass:: Filter + :members: + :inherited-members: + :undoc-members: + +.. autoclass:: MarkedChangesFilter + :members: + :inherited-members: + :undoc-members: + +.. autoclass:: FilteredCache + :members: + :inherited-members: + :undoc-members: + + +Example +^^^^^^^ + +This is an example for a filtered cache, which only allows access to the +packages whose state has been changed, eg. packages marked for installation:: + + >>> from apt.cache import FilteredCache, Cache, MarkedChangesFilter + >>> cache = apt.Cache() + >>> changed = apt.FilteredCache(cache) + >>> changed.set_filter(MarkedChangesFilter()) + >>> print(len(changed) == len(cache.get_changes())) # Both need to have same length + True + +The ProblemResolver class +-------------------------- + +.. autoclass:: ProblemResolver + :members: + +Exceptions +---------- +.. autoexception:: FetchCancelledException +.. autoexception:: FetchFailedException +.. autoexception:: LockFailedException diff --git a/doc/source/library/apt.cdrom.rst b/doc/source/library/apt.cdrom.rst new file mode 100644 index 0000000..56381f1 --- /dev/null +++ b/doc/source/library/apt.cdrom.rst @@ -0,0 +1,7 @@ +:mod:`apt.cdrom` - Functionality like in apt-cdrom +==================================================== +.. automodule:: apt.cdrom + :members: + + + diff --git a/doc/source/library/apt.debfile.rst b/doc/source/library/apt.debfile.rst new file mode 100644 index 0000000..7133b5a --- /dev/null +++ b/doc/source/library/apt.debfile.rst @@ -0,0 +1,39 @@ +:mod:`apt.debfile` --- Classes related to debian package files +============================================================== +The :mod:`apt.debfile` provides classes to work with locally available +debian packages, or source packages. + +.. module:: apt.debfile + +Binary packages +---------------- +.. autoclass:: DebPackage + :members: + :inherited-members: + :undoc-members: + + The :class:`DebPackage` class is a class for working with '.deb' files, + also known as Debian packages. + + It provides methods and attributes to get a list of the files in the + package, to install the package and much more. + + If you specify *cache* it has to point to an :class:`apt.cache.Cache()` + object. + + .. versionchanged:: 0.7.9 + Introduce all new methods (everything except for :meth:`open()` and + :attr:`filelist`) + + +Source packages +---------------- +.. autoclass:: DscSrcPackage + :members: + :inherited-members: + :undoc-members: + + Provide functionality to work with locally available source packages, + especially with their '.dsc' file. + + .. versionadded:: 0.7.9 diff --git a/doc/source/library/apt.package.rst b/doc/source/library/apt.package.rst new file mode 100644 index 0000000..ec7ed36 --- /dev/null +++ b/doc/source/library/apt.package.rst @@ -0,0 +1,122 @@ +:mod:`apt.package` --- Classes for package handling +==================================================== + + +.. automodule:: apt.package + + +The Package class +----------------- +.. autoclass:: Package + :members: + + .. note:: + + Several methods have been deprecated in version 0.7.9 of python-apt, + please see the :class:`Version` class for the new alternatives. + +The Version class +----------------- +.. autoclass:: Version + :members: + + +Dependency Information +---------------------- +.. autoclass:: BaseDependency + :members: + +.. class:: Dependency + + The dependency class represents a Or-Group of dependencies. It provides + an attribute to access the :class:`BaseDependency` object for the available + choices. + + .. attribute:: or_dependencies + + A list of :class:`BaseDependency` objects which could satisfy the + requirement of the Or-Group. + + +Origin Information +------------------- +.. class:: Origin + + The :class:`Origin` class provides access to the origin of the package. + It allows you to check the component, archive, the hostname, and even if + this package can be trusted. + + .. attribute:: archive + + The archive (eg. unstable) + + .. attribute:: component + + The component (eg. main) + + .. attribute:: label + + The Label, as set in the Release file + + .. attribute:: origin + + The Origin, as set in the Release file + + .. attribute:: site + + The hostname of the site. + + .. attribute:: trusted + + Boolean value whether this is trustworthy. An origin can be trusted, if + it provides a GPG-signed Release file and the GPG-key used is in the + keyring used by apt (see apt-key). + + + +The Record class +----------------- +.. autoclass:: Record + :members: + + .. note:: + .. versionchanged:: 0.7.100 + This class is a subclass of :class:`collections.Mapping` when used + in Python 2.6 or newer. + + .. describe:: record[name] + + Return the value of the field with the name *name*. + + .. describe:: name in record + + Return whether a field *name* exists in record. + + .. describe:: len(record) + + The number of fields in the record + + .. describe:: str(record) + + Display the record as a string + + +Examples +--------- +.. code-block:: python + + import apt + + cache = apt.Cache() + pkg = cache['python-apt'] # Access the Package object for python-apt + print('python-apt is trusted:', pkg.candidate.origins[0].trusted) + + # Mark python-apt for install + pkg.mark_install() + + print('python-apt is marked for install:', pkg.marked_install) + + print('python-apt is (summary):', pkg.candidate.summary) + + # Now, really install it + cache.commit() diff --git a/doc/source/library/apt.progress.base.rst b/doc/source/library/apt.progress.base.rst new file mode 100644 index 0000000..7d43fe9 --- /dev/null +++ b/doc/source/library/apt.progress.base.rst @@ -0,0 +1,335 @@ +:mod:`apt.progress.base` --- Abstract classes for progress reporting +==================================================================== +.. module:: apt.progress.base + +This module provides base classes for progress handlers from which all +progress classes should inherit from. Progress reporting classes not +inheriting from those classes may not work and are not supported. + +When creating a subclass of one of those classes, all overridden methods should +call the parent's method first before doing anything else, because the parent +method may have to set some attributes. Subclasses not doing so may not work +correctly or may not work at all and are completely unsupported. + +AcquireProgress +--------------- +.. class:: AcquireProgress + + A monitor object for downloads controlled by the Acquire class. This base + class does nothing and should only be used as a base class to inherit + from. Instances of this class can be passed to the constructor of + :class:`apt_pkg.Acquire` and the Acquire object then uses it to report + its progress. + + This class provides several methods which may be overridden by subclasses + to implement progress reporting: + + .. method:: done(item: apt_pkg.AcquireItemDesc) + + Invoked when an item is successfully and completely fetched. + + .. method:: fail(item: apt_pkg.AcquireItemDesc) + + Invoked when the process of fetching an item encounters a fatal error + like a non existing file or no connection to the server. + + .. method:: fetch(item: apt_pkg.AcquireItemDesc) + + Invoked when some of the item's data is fetched. This normally means + that the file is being fetched now and e.g. the headers have been + retrieved already. + + .. method:: ims_hit(item: apt_pkg.AcquireItemDesc) + + Invoked when an item is confirmed to be up-to-date. For instance, + when an HTTP download is informed that the file on the server was + not modified. + + .. method:: media_change(media: str, drive: str) -> bool + + Prompt the user to change the inserted removable media. This function + is called whenever a media change is needed to ask the user to insert + the needed media. + + The parameter *media* decribes the name of the media type that + should be changed, whereas the parameter *drive* should be the + identifying name of the drive whose media should be changed. + + This method should not return until the user has confirmed to the user + interface that the media change is complete. It must return True if + the user confirms the media change, or False to cancel it. + + .. method:: pulse(owner: apt_pkg.Acquire) -> bool + + This method gets invoked while the Acquire progress given by the + parameter *owner* is underway. It should display information about + the current state. It must return ``True`` to continue the acquistion + or ``False`` to cancel it. This base implementation always returns + ``True``. + + .. method:: start() + + Invoked when the Acquire process starts running. + + .. method:: stop() + + Invoked when the Acquire process stops running. + + In addition to those methods, this class provides several attributes which + are set automatically and represent the fetch progress: + + .. attribute:: current_bytes + + The number of bytes fetched. + + .. attribute:: current_cps + + The current rate of download, in bytes per second. + + .. attribute:: current_items + + The number of items that have been successfully downloaded. + + .. attribute:: elapsed_time + + The amount of time that has elapsed since the download started. + + .. attribute:: fetched_bytes + + The total number of bytes accounted for by items that were + successfully fetched. + + .. attribute:: last_bytes + + The number of bytes fetched as of the previous call to pulse(), + including local items. + + .. attribute:: total_bytes + + The total number of bytes that need to be fetched. This member is + inaccurate, as new items might be enqueued while the download is + in progress! + + .. attribute:: total_items + + The total number of items that need to be fetched. This member is + inaccurate, as new items might be enqueued while the download is + in progress! + + +CdromProgress +------------- +.. class:: CdromProgress + + Base class for reporting the progress of adding a cdrom which could be + used with apt_pkg.Cdrom to produce an utility like apt-cdrom. + + Methods defined here: + + .. method:: ask_cdrom_name() -> str + + Ask for the name of the cdrom. This method is called when a CD-ROM + is added (e.g. via :meth:`apt_pkg.Cdrom.add`) and no label for the + CD-ROM can be found. + + Implementations should request a label from the user (e.g. via + :func:`raw_input`) and return this label from the function. The + operation can be cancelled if the function returns ``None`` instead + of a string. + + .. method:: change_cdrom() -> bool + + Ask for the CD-ROM to be changed. This method should return ``True`` + if the CD-ROM has been changed or ``False`` if the CD-ROM has not been + changed and the operation should be cancelled. This base implementation + returns ``False`` and thus cancels the operation. + + .. method:: update(text: str, current: int) + + Periodically invoked in order to update the interface and give + information about the progress of the operation. + + This method has two parameters. The first parameter *text* defines + the text which should be displayed to the user as the progress + message. The second parameter *current* is an integer describing how + many steps have been completed already. + + .. attribute:: total_steps + + The number of total steps, set automatically by python-apt. It may be + used in conjunction with the parameter *current* of the :meth:`update` + method to show how far the operation progressed. + + +OpProgress +---------- +.. class:: OpProgress + + OpProgress classes are used for reporting the progress of operations + such as opening the cache. It is based on the concept of one operation + consisting of a series of sub operations. + + Methods defined here: + + .. method:: done() + + Called once an operation has been completed. + + .. method:: update([percent=None]) + + Called periodically to update the user interface. This function should + use the attributes defined below to display the progress information. + + The optional parameter *percent* is included for compatibility + reasons and may be removed at a later time. + + The following attributes are available and are changed by the classes + wanting to emit progress: + + .. attribute:: major_change + + An automatically set boolean value describing whether the current call + to update is caused by a major change. In this case, the last operation + has finished. + + .. attribute:: op + + An automatically set string which describes the current operation in + an human-readable way. + + .. attribute:: percent + + An automatically set float value describing how much of the operation + has been completed, in percent. + + .. attribute:: subop + + An automatically set string which describes the current sub-operation + in an human-readable way. + + +InstallProgress +--------------- +.. class:: InstallProgress + + InstallProgress classes make it possible to monitor the progress of dpkg + and APT and emit information at certain stages. It uses file descriptors + to read the status lines from APT/dpkg and parses them and afterwards calls + the callback methods. + + Subclasses should override the following methods in order to implement + progress reporting: + + .. method:: conffile(current, new) + + Called when a conffile question from dpkg is detected. + + .. note:: + + This part of the API is semi-stable and may be extended with 2 more + parameters before the release of 0.7.100. + + .. method:: error(pkg, errormsg) + + (Abstract) Called when a error is detected during the install. + + The following method should be overridden to implement progress reporting + for dpkg-based runs i.e. calls to :meth:`run` with a filename: + + .. method:: processing(pkg, stage) + + This method is called just before a processing stage starts. The + parameter *pkg* is the name of the package and the parameter *stage* + is one of the stages listed in the dpkg manual under the status-fd + option, i.e. "upgrade", "install" (both sent before unpacking), + "configure", "trigproc", "remove", "purge". + + .. method:: dpkg_status_change(pkg: str, status: str) + + This method is called whenever the dpkg status of the package + changes. The parameter *pkg* is the name of the package and the + parameter *status* is one of the status strings used in the status + file (:file:`/var/lib/dpkg/status`) and documented + in :manpage:`dpkg(1)`. + + The following methods should be overridden to implement progress reporting + for :meth:`run` calls with an :class:`apt_pkg.PackageManager` object as + their parameter: + + .. method:: status_change(pkg, percent, status) + + This method implements progress reporting for package installation by + APT and may be extended to dpkg at a later time. + + This method takes two parameters: The parameter *percent* is a float + value describing the overall progress and the parameter *status* is a + string describing the current status in an human-readable manner. + + .. method:: start_update() + + This method is called before the installation of any package starts. + + .. method:: finish_update() + + This method is called when all changes have been applied. + + There are also several methods which are fully implemented and should not + be overridden by subclasses unless the subclass has very special needs: + + .. method:: fork() -> int + + Fork a child process and return 0 to the child process and the PID of + the child to the parent process. This implementation just calls + :func:`os.fork` and returns its value. + + .. method:: run(obj) + + This method runs install actions. The parameter *obj* may either + be a PackageManager object in which case its **do_install()** method is + called or the path to a deb file. + + If the object is a :class:`apt_pkg.PackageManager`, the functions + returns the result of calling its ``do_install()`` method. Otherwise, + the function returns the exit status of dpkg. In both cases, ``0`` + means that there were no problems and ``!= 0`` means that there were + issues. + + .. method:: update_interface() + + This method is responsible for reading the status from dpkg/APT and + calling the correct callback methods. Subclasses should not override + this method. + + .. method:: wait_child() + + This method is responsible for calling :meth:`update_interface` from + time to time. It exits once the child has exited. The return value + is the full status returned by :func:`os.waitpid` (not only the + return code). Subclasses should not override this method. + + The class also provides several attributes which may be useful: + + .. attribute:: percent + + The percentage of completion as it was in the last call to + :meth:`status_change`. + + .. attribute:: status + + The status string passed in the last call to :meth:`status_change`. + + .. attribute:: select_timeout + + Used in :meth:`wait_child` to when calling :func:`select.select` + on dpkg's/APT's status descriptor. Subclasses may set their own value + if needed. + + .. attribute:: statusfd + + A readable :class:`file` object from which the status information from + APT or dpkg is read. + + .. attribute:: writefd + + A writable :class:`file` object to which dpkg or APT write their status + information. diff --git a/doc/source/library/apt.progress.text.rst b/doc/source/library/apt.progress.text.rst new file mode 100644 index 0000000..4e051e3 --- /dev/null +++ b/doc/source/library/apt.progress.text.rst @@ -0,0 +1,21 @@ +:mod:`apt.progress.text` --- Progress reporting for text interfaces +=================================================================== +.. automodule:: apt.progress.text + + +Acquire Progress Reporting +-------------------------- +.. autoclass:: AcquireProgress + :members: + + +CD-ROM Progress Reporting +-------------------------- +.. autoclass:: CdromProgress + :members: + +Operation Progress Reporting +----------------------------- +.. autoclass:: OpProgress + :members: + diff --git a/doc/source/library/apt_inst.rst b/doc/source/library/apt_inst.rst new file mode 100644 index 0000000..6ba330a --- /dev/null +++ b/doc/source/library/apt_inst.rst @@ -0,0 +1,323 @@ +:mod:`apt_inst` - Working with local Debian packages +==================================================== +.. module:: apt_inst + +This module provides useful classes and functions to work with archives, +modelled after the :class:`tarfile.TarFile` class. For working with Debian +packages, the :class:`DebFile` class should be used as it provides easy access +to the control.tar.* and data.tar.* members. + +The classes are mostly modeled after the :class:`tarfile.TarFile` class and +enhanced with APT-specific methods. Because APT only provides a stream based +view on a tar archive, this module's :class:`TarFile` class only provides a +very small subset of those functions. + +Exceptions +---------- + +.. class:: Error + + This is the same class as :class:`apt_pkg.Error`, provided here for + convenience. + +AR Archives +----------- +.. class:: ArArchive(file) + + An ArArchive object represents an archive in the 4.4 BSD AR format, + which is used for e.g. deb packages. + + The parameter *file* may be a string specifying the path of a file, or + a :class:`file`-like object providing the :meth:`fileno` method. It may + also be an int specifying a file descriptor (returned by e.g. + :func:`os.open`). The recommended way is to pass in the path to the file. + + ArArchive (and its subclasses) support the iterator protocol, meaning that + an :class:`ArArchive` object can be iterated over yielding the members in + the archive (same as :meth:`getmembers`). + + .. describe:: archive[key] + + Return a ArMember object for the member given by *key*. Raise + LookupError if there is no ArMember with the given name. + + .. describe:: key in archive + + Return True if a member with the name *key* is found in the archive, it + is the same function as :meth:`getmember`. + + .. method:: extract(name[, target: str]) -> bool + + Extract the member given by *name* into the directory given by + *target*. If the extraction failed, an error is raised. Otherwise, + the method returns True if the owner could be set or False if the + owner could not be changed. It may also raise LookupError if there + is no member with the given name. + + The parameter *target* is completely optional. If it is not given, the + function extracts into the current directory. + + .. method:: extractall([target: str]) -> bool + + Extract all into the directory given by target or the current + directory if target is not given. If the extraction failed, an error + is raised. Otherwise, the method returns True if the owner could be + set or False if the owner could not be changed. + + .. method:: extractdata(name: str) -> bytes + + Return the contents of the member given by *name*, as a bytes object. + Raise LookupError if there is no ArMember with the given name. + + .. method:: getmember(name: str) -> ArMember + + Return a ArMember object for the member given by *name*. Raise + LookupError if there is no ArMember with the given name. + + .. method:: getmembers() -> list + + Return a list of all members in the AR archive. + + .. method:: getnames() -> list + + Return a list of the names of all members in the AR archive. + + .. method:: gettar(name: str, comp: str) -> TarFile + + Return a TarFile object for the member given by *name* which will be + decompressed using the compression algorithm given by *comp*. + This is almost equal to:: + + member = arfile.getmember(name) + tarfile = TarFile(file, member.start, member.size, 'gzip')' + + It just opens a new TarFile on the given position in the stream. + +.. class:: ArMember + + An ArMember object represents a single file within an AR archive. For + Debian packages this can be e.g. control.tar.gz. This class provides + information about this file, such as the mode and size. It has no + constructor. + + .. attribute:: gid + + The group id of the owner. + + .. attribute:: mode + + The mode of the file. + + .. attribute:: mtime + + Last time of modification. + + .. attribute:: name + + The name of the file. + + .. attribute:: size + + The size of the files. + + .. attribute:: start + + The offset in the archive where the file starts. + + .. attribute:: uid + + The user id of the owner. + +Debian Packages +--------------- +.. class:: DebFile(file) + + A DebFile object represents a file in the .deb package format. It inherits + :class:`ArArchive`. In addition to the attributes and methods from + :class:`ArArchive`, DebFile provides the following methods: + + .. attribute:: control + + The :class:`TarFile` object associated with the control.tar.gz member. + + .. attribute:: data + + The :class:`TarFile` object associated with the + data.tar.{gz,bz2,lzma,xz} member. + + .. attribute:: debian_binary + + The package version, as contained in debian-binary. + +Tar Archives +------------- +.. class:: TarFile(file[, min: int, max: int, comp: str]) + + A TarFile object represents a single .tar file stream. + + The parameter *file* may be a string specifying the path of a file, or + a :class:`file`-like object providing the :meth:`fileno` method. It may + also be an int specifying a file descriptor (returned by e.g. + :func:`os.open`). + + The parameter *min* describes the offset in the file where the archive + begins and the parameter *max* is the size of the archive. + + The compression of the archive is set by the parameter *comp*. It can + be set to any program supporting the -d switch, the default being gzip. + + .. method:: extractall([rootdir: str]) -> True + + Extract the archive in the current directory. The argument *rootdir* + can be used to change the target directory. + + .. method:: extractdata(member: str) -> bytes + + Return the contents of the member, as a bytes object. Raise + LookupError if there is no member with the given name. + + .. method:: go(callback: callable[, member: str]) -> True + + Go through the archive and call the callable *callback* for each + member with 2 arguments. The first argument is the :class:`TarMember` + and the second one is the data, as bytes. + + The optional parameter *member* can be used to specify the member for + which call the callback. If not specified, it will be called for all + members. If specified and not found, LookupError will be raised. + +.. class:: TarMember + + Represent a single member of a 'tar' archive. + + This class which has been modelled after :class:`tarfile.TarInfo` + represents information about a given member in an archive. + + .. method:: isblk() + + Determine whether the member is a block device. + + .. method:: ischr() + + Determine whether the member is a character device. + + .. method:: isdev() + + Determine whether the member is a device (block,character or FIFO). + + .. method:: isdir() + + Determine whether the member is a directory. + + .. method:: isfifo() + + Determine whether the member is a FIFO. + + .. method:: isfile() + + Determine whether the member is a regular file. + + .. method:: islnk() + + Determine whether the member is a hardlink. + + .. method:: isreg() + + Determine whether the member is a regular file, same as isfile(). + + .. method:: issym() + + Determine whether the member is a symbolic link. + + .. attribute:: gid + + The owner's group id + + .. attribute:: linkname + + The target of the link. + + .. attribute:: major + + The major ID of the device. + + .. attribute:: minor + + The minor ID of the device. + + .. attribute:: mode + + The mode (permissions). + + .. attribute:: mtime + + Last time of modification. + + .. attribute:: name + + The name of the file. + + .. attribute:: size + + The size of the file. + + .. attribute:: uid + + The owner's user id. + + + +Removed functions +--------------------- +The following functions have been removed in python-apt 0.8. +They are listed here to help developers port their applications to the new +API which is completely different. For this purpose each function documentation +includes an example showing how the function can be replaced. + +.. function:: arCheckMember(file, membername) + + This function has been replaced by using the :keyword:`in` check on an + :class:`ArArchive` object:: + + member in ArArchive(file) + +.. function:: debExtract(file, func, chunk) + + This function has been replaced by the :meth:`TarFile.go` + method. The following example shows the old code and the new code:: + + debExtract(open("package.deb"), my_callback, "data.tar.gz") #old + + DebFile("package.deb").data.go(my_callback) + + Please note that the signature of the callback is different in + :meth:`TarFile.go`. + +.. function:: tarExtract(file,func,comp) + + This function has been replaced by the :meth:`TarFile.go` + method. The following example shows the old code and the new code:: + + tarExtract(open("archive.tar.gz"), my_callback, "gzip") #old + TarFile("archive.tar.gz", 0, 0, "gzip").go(my_callback) + + Please note that the signature of the callback is different in + :meth:`TarFile.go`, it now expects a :class:`TarMember` and a bytestring + of the data. + +.. function:: debExtractArchive(file, rootdir) + + This function has been replaced by :meth:`TarFile.extractall` and + :attr:`DebFile.data`:: + + debExtractArchive(open("package.deb"), rootdir) # old + DebFile("package.deb").data.extractall(rootdir) # new + +.. function:: debExtractControl(file[, member='control']) + + This function has been replaced by :attr:`DebFile.control` and + :meth:`TarFile.extractdata`. In the following example, both commands + return the contents of the control file:: + + debExtractControl(open("package.deb")) + DebFile("package.deb").control.extractdata("control") diff --git a/doc/source/library/apt_pkg.rst b/doc/source/library/apt_pkg.rst new file mode 100644 index 0000000..4290180 --- /dev/null +++ b/doc/source/library/apt_pkg.rst @@ -0,0 +1,2904 @@ +:mod:`apt_pkg` --- The low-level bindings for apt-pkg +===================================================== +.. module:: apt_pkg + +The apt_pkg extensions provides a more low-level way to work with apt. It can +do everything apt can, and is written in C++. It has been in python-apt since +the beginning. + +Module Initialization +--------------------- + +Initialization is needed for most functions, but not for all of them. Some can +be called without having run init*(), but will not return the expected value. + +.. function:: init_config + + Initialize the configuration of apt. This is needed for most operations. + +.. function:: init_system + + Initialize the system. + +.. function:: init + + A short cut to calling :func:`init_config` and :func:`init_system`. You + can use this if you do not use the command line parsing facilities provided + by :func:`parse_commandline`, otherwise call :func:`init_config`, parse + the commandline afterwards and finally call :func:`init_system`. + + +Exceptions +---------- +.. autoclass:: Error + +.. autoclass:: CacheMismatchError + + +Working with the cache +---------------------- +.. class:: Cache([progress: apt.progress.base.OpProgress]) + + A Cache object represents the cache used by APT which contains information + about packages. The object itself provides no means to modify the cache or + the installed packages, see the classes :class:`DepCache` and + :class:`PackageManager` for such functionality. + + The constructor takes an optional argument which must be a subclass of + :class:`apt.progress.base.OpProgress`. This object will then be used to + display information during the cache opening process (or possible creation + of the cache). It may also be ``None``, in which case no progress will + be emitted. If not given, progress will be printed to standard output. + + .. note:: + + The cache supports colon-separated name:architecture pairs. For + normal architectures, they are equal to a (name, architecture) + tuple. For the "any" architecture behavior is different, as + "name:any" is equivalent to ("name:any", "any"). This is done so + that "name:any" matches all packages with that name which have + Multi-Arch: allowed set. + + .. describe:: cache[pkgname] + + Return the :class:`Package()` object for the package name given by + *pkgname*. If *pkgname* includes a colon, the part after the colon + is used as the architecture. + + .. describe:: cache[name, architecture] + + Return the :class:`Package()` object for the package with the given + name and architecture. + + .. versionadded: 0.8.0 + + .. describe:: pkgname in cache + + Check whether a package with the name given by *pkgname* exists in + the cache for the native architecture. If *pkgname* includes a + colon, the part after the colon is used as the architecture. + + .. describe:: (name, architecture) in cache + + Check whether a package with the given name and architecture exists + in the cache. + + .. versionadded: 0.8.0 + + .. method:: update(progress, sources [, pulse_interval]) -> bool + + Update the index files used by the cache. A call to this method + does not affect the current Cache object, instead a new one + should be created in order to use the changed index files. + + The parameter *progress* takes an + :class:`apt.progress.base.AcquireProgress` object which will display + the progress of fetching the index files. The parameter *sources* takes + a :class:`SourceList` object which lists the sources. The parameter + *progress* takes an integer describing the interval (in microseconds) + in which the pulse() method of the *progress* object will be called. + + .. attribute:: depends_count + + The total number of dependencies stored in the cache. + + .. attribute:: file_list + + A list of all :class:`PackageFile` objects stored in the cache. + + .. attribute:: group_count + + The number of groups in the cache. + + .. versionadded: 0.8.0 + + .. attribute:: groups + + A sequence of :class:`Group` objects, implemented as a + :class:`GroupList` object. + + .. versionadded: 0.8.0 + + .. class:: GroupList + + A simple sequence-like object which only provides a length and + an implementation of ``__getitem__`` for accessing groups at + a certain index. Apart from being iterable, it can be used in + the following ways: + + .. versionadded: 0.8.0 + + .. describe:: list[index] + + Get the :class:`Group` object for the group at the position + given by *index* in the GroupList *list*. + + .. describe:: len(list) + + Return the length of the GroupList object *list*. + + + .. attribute:: is_multi_arch + + An attribute determining whether the cache supports multi-arch. + + .. versionadded: 0.8.0 + + .. attribute:: package_count + + The total number of packages available in the cache. This value is + equal to the length of the list provided by the :attr:`packages` + attribute. + + .. attribute:: package_file_count + + The total number of Packages files available (the Packages files + listing the packages). This is the same as the length of the list in + the attribute :attr:`file_list`. + + .. attribute:: packages + + A sequence of :class:`Package` objects, implemented as a + :class:`PackageList` object. + + .. class:: PackageList + + A simple sequence-like object which only provides a length and + an implementation of ``__getitem__`` for accessing packages at + a certain index. Apart from being iterable, it can be used in + the following ways: + + .. describe:: list[index] + + Get the :class:`Package` object for the package at the position + given by *index* in the PackageList *list*. + + .. describe:: len(list) + + Return the length of the PackageList object *list*. + + .. attribute:: provides_count + + The number of provided packages. + + .. attribute:: ver_file_count + + The total number of ``(Version, PackageFile)`` relations stored in + the cache. + + .. attribute:: version_count + + The total number of package versions available in the cache. + +Managing the cache with :class:`DepCache` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. class:: DepCache(cache: apt_pkg.Cache) + + A DepCache object provides access to more information about the + objects made available by the :class:`Cache` object as well as + means to mark packages for removal and installation, among other + actions. + + The constructor takes a single argument which specifies the + :class:`Cache` object the new object shall be related to. While + it is theoretically possible to create multiple DepCache objects + for the same cache, they will not be independent from each other + since they all access the same underlying C++ object. + + Objects of this type provide several methods. Most of those methods + are safe to use and should never raise any exception (all those + methods for requesting state information or marking changes). If a + method is expected to raise an exception, it will be stated in the + description. + + If an object of a different cache is passed, :class:`CacheMismatchError` + is raised. + + .. method:: commit(acquire_progress, install_progress) + + Commit all marked changes, while reporting the progress of + fetching packages via the :class:`apt.progress.base.AcquireProgress` + object given by *acquire_progress* and reporting the installation + of the package using the :class:`apt.progress.base.InstallProgress` + object given by *install_progress*. + + If this fails, an exception of the type :exc:`SystemError` will + be raised. + + .. method:: fix_broken() -> bool + + Try to fix all broken packages in the cache and return ``True`` in + case of success. If an error occurred, a :exc:`SystemError` + exception is raised. + + .. method:: get_candidate_ver(pkg: Package) -> Version + + Return the candidate version for the package given by the parameter + *pkg* as a :class:`Version` object. The default candidate for a + package is the version with the highest pin, although a different + one may be set using :meth:`set_candidate_ver`. If no candidate + can be found, return ``None`` instead. + + .. method:: init(progress: apt.progress.base.OpProgress) + + Initialize the DepCache. This is done automatically when the + cache is opened, but sometimes it may be useful to reinitialize + the DepCache. Like the constructor of :class:`Cache`, this + function takes a single :class:`apt.progress.base.OpProgress` + object to display progress information. + + .. method:: read_pinfile(file: str) + + A proxy function which calls the method :meth:`Policy.read_pinfile` of + the :class:`Policy` object used by this object. This method raises + a :exc:`SystemError` exception if the file could not be parsed. + + .. method:: set_candidate_ver(pkg: Package, version: Version) -> bool + + Set the candidate version of the package given by the :class:`Package` + object *pkg* to the version given by the :class:`Version` object + *version* and return ``True``. If odd things happen, this function + may raise a :exc:`SystemError` exception, but this should not + happen in normal usage. See :meth:`get_candidate_ver` for a way + to retrieve the candidate version of a package. + + .. method:: upgrade([dist_upgrade=False]) -> bool + + Mark the packages for upgrade under the same conditions + :program:`apt-get` does. If *dist_upgrade* is ``True``, also + allow packages to be upgraded if they require installation/removal + of other packages; just like apt-get dist-upgrade. + + Despite returning a boolean value, this raises :exc:`SystemError` and + does not return ``False`` if an error occurred. + + The following methods can mark a single package for installation, + removal, etc: + + .. method:: mark_auto(pkg: Package) + + Mark the :class:`Package` *pkg* as automatically installed. + + .. method:: mark_keep(pkg: Package) + + Mark the :class:`Package` *pkg* for keep. + + .. method:: mark_delete(pkg: Package[, purge]) + + Mark the :class:`Package` *pkg* for delete. If *purge* is True, + the configuration files will be removed as well. + + .. method:: mark_install(pkg: Package[, auto_inst=True[, from_user=True]]) + + Mark the :class:`Package` *pkg* for install, and, if *auto_inst* + is ``True``, its dependencies as well. If *from_user* is ``True``, + the package will **not** be marked as automatically installed. + + .. method:: set_reinstall(pkg: Package) + + Set if the :class:`Package` *pkg* should be reinstalled. + + The following methods can be used to check the state of a package: + + .. method:: is_auto_installed(pkg: Package) -> bool + + Return ``True`` if the package is automatically installed, that + is, as a dependency of another package. + + .. method:: is_garbage(pkg: Package) -> bool + + Return ``True`` if the package is garbage, that is, if it was + automatically installed and no longer referenced by other packages. + + .. method:: is_inst_broken(pkg: Package) -> bool + + Return ``True`` if the package is broken on the current install. This + takes changes which have not been marked not into account. + + .. method:: is_now_broken(pkg: Package) -> bool + + Return ``True`` if the package is now broken, that is, if the package + is broken if the marked changes are applied. + + .. method:: is_upgradable(pkg: Package) -> bool + + Return ``True`` if the package is upgradable, the package can then + be marked for upgrade by calling the method :meth:`mark_install`. + + .. method:: marked_delete(pkg: Package) -> bool + + Return ``True`` if the package is marked for delete. + + .. method:: marked_downgrade(pkg: Package) -> bool + + Return ``True`` if the package should be downgraded. + + .. method:: marked_install(pkg: Package) -> bool + + Return ``True`` if the package is marked for install. + + .. method:: marked_keep(pkg: Package) -> bool + + Return ``True`` if the package is marked for keep. + + .. method:: marked_reinstall(pkg: Package) -> bool + + Return ``True`` if the package should be reinstalled. + + .. method:: marked_upgrade(pkg: Package) -> bool + + Return ``True`` if the package is marked for upgrade. + + .. method:: phasing_applied(pkg: Package) -> bool + + Return ``True`` if the package update is being phased. + + DepCache objects also provide several attributes containing information + on the marked changes: + + .. attribute:: keep_count + + Integer, number of packages marked as keep + + .. attribute:: inst_count + + Integer, number of packages marked for installation. + + .. attribute:: del_count + + Number of packages which should be removed. + + .. attribute:: broken_count + + Number of packages which are broken. + + .. attribute:: usr_size + + The size required for the changes on the filesystem. If you install + packages, this is positive, if you remove them its negative. + + .. attribute:: deb_size + + The size of the packages which are needed for the changes to be + applied. + + .. attribute:: policy + + The underlying :class:`Policy` object used by the :class:`DepCache` to + select candidate versions. + +Installing with :class:`PackageManager` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. class:: PackageManager(depcache) + + Abstraction of a package manager. This object takes care of retrieving + packages, ordering the installation, and calling the package manager to + do the actual installation. + + .. method:: get_archives(fetcher, list, records) -> bool + + Add all packages marked for installation (or upgrade, anything + which needs a download) to the :class:`Acquire` object referenced + by *fetcher*. + + The parameter *list* specifies a :class:`SourceList` object which + is used to retrieve the information about the archive URI for the + packages which will be fetched. + + The parameter *records* takes a :class:`PackageRecords` object which + will be used to look up the file name of the package. + + .. method:: do_install(status_fd: int) -> int + + Install the packages and return one of the class constants + :attr:`RESULT_COMPLETED`, :attr:`RESULT_FAILED`, + :attr:`RESULT_INCOMPLETE`. The argument *status_fd* can be used + to specify a file descriptor that APT will write status information + on (see README.progress-reporting in the apt source code for + information on what will be written there). + + .. method:: fix_missing() -> bool + + Fix the installation if a package could not be downloaded. + + .. attribute:: RESULT_COMPLETED + + A constant for checking whether the result of the call to + :meth:`do_install` is 'failed'. + + .. attribute:: RESULT_FAILED + + A constant for checking whether the result of the call to + :meth:`do_install` is 'failed'. + + .. attribute:: RESULT_INCOMPLETE + + A constant for checking whether the result of the call to + :meth:`do_install` is 'incomplete'. + + All instances of this class also support the following methods: + + .. note:: + + This methods are provided mainly for subclassing purposes + and should not be used in most programs. This class is a + subclass of an internal :class:`_PackageManager` which does + not provide that methods. As the public C++ API creates such + an object without those methods, you should not rely on those + methods to be available unless you used the constructor of + :class:`PackageManager` to create the object. + + .. method:: configure(pkg: Package) -> bool + + Notify the package manager that the :class:`Package` given + by *pkg* is to be configured. Must return a ``True`` value + or ``None`` to continue, or a value which is ``False`` if + evaluated as boolean to abort. + + .. versionadded:: 0.8.0 + + .. method:: install(pkg: Package, filename: str) -> bool + + Notify the package manager that the :class:`Package` given + by *pkg* is to be installed from the .deb located at + *filename*. Must return a ``True`` value or ``None`` to + continue, or a value which is ``False`` if evaluated as + boolean to abort. + + + .. versionadded:: 0.8.0 + + .. method:: remove(pkg: Package, purge: bool) -> bool + + Notify the package manager that the :class:`Package` given + by *pkg* is to be removed. If *purge* is ``True``, the package + shall be purged. Must return a ``True`` value or ``None`` to + continue, or a value which is ``False`` if evaluated as boolean + to abort. + + + .. versionadded:: 0.8.0 + + .. method:: go(status_fd: int) -> bool + + Start dpkg, writing status information to the file descriptor + given by *status_fd*. Must return a ``True`` value or ``None`` to + continue, or a value which is ``False`` if evaluated as boolean + to abort. + + .. versionadded:: 0.8.0 + + .. method:: reset() + + Reset the package manager for a new round. + + .. versionadded:: 0.8.0 + + +Installation ordering with :class:`OrderList` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. class:: OrderList(depcache: DepCache) + + Represent a :c:type:`pkgOrderList`, used for installation + ordering. This class provides several methods and attributes, + is complicated and should not be used by normal programs. + + .. versionadded:: 0.8.0 + + This class is a sequence and supports the following operations: + + .. describe:: list[index] + + Get the package at the given index in the list. Negative + index is supported. + + .. describe:: len(list) + + The length of the list. + + It also supports the append() method from :class:`list`: + + .. method:: append(pkg: Package) + + Append a new package to the end of the list. Please note that + you may not append a package twice, as only as much packages + as in the cache can be added. + + The class also defines several specific attributes and methods, + to be described hereinafter. + + .. method:: score(pkg: Package) + + Return the score of the package. Packages are basically + ordered by descending score. + + This class allows flags to be set on packages. Those flags are: + + .. attribute:: FLAG_ADDED + .. attribute:: FLAG_ADD_PENDING + .. attribute:: FLAG_IMMEDIATE + .. attribute:: FLAG_LOOP + .. attribute:: FLAG_UNPACKED + .. attribute:: FLAG_CONFIGURED + .. attribute:: FLAG_REMOVED + .. attribute:: FLAG_STATES_MASK + + Same as ``FLAG_UNPACKED | FLAG_CONFIGURED | FLAG_REMOVED`` + + .. attribute:: FLAG_IN_LIST + .. attribute:: FLAG_AFTER + + The methods to work with those flags are: + + .. method:: flag(pkg: Package, flag: int[, unset_flags: int]) + + Flag a package. Sets the flags given in *flag* and unsets + any flags given in *unset_flags*. + + .. method:: is_flag(pkg: Package, flag: int) + + Check whether the flags in *flag* are set for the package. + + .. method:: wipe_flags(flags: int) + + Remove the flags in *flags* from all packages. + + .. method:: is_missing(pkg: Package) + + Check if the package is missing (not really usable right now) + + .. method:: is_now(pkg: Package) + + Check if the package is flagged for any state but removal. + + The following methods for ordering are provided: + + .. method:: order_critical() + + Order the packages for critical unpacking; that is, only + respect pre-dependencies. + + .. method:: order_unpack() + + Order the packages for unpacking, repecting Pre-Depends and + Conflicts. + + .. method:: order_configure() + + Order the packages for configuration, respecting Depends. + +Improve performance with :class:`ActionGroup` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. class:: ActionGroup(depcache) + + Create a new :class:`ActionGroup()` object for the :class:`DepCache` object + given by the parameter *depcache*. + + :class:`ActionGroup()` objects make operations on the cache faster by + delaying certain cleanup operations until the action group is released. + + An action group is also a context manager and therefore supports the + :keyword:`with` statement. But because it becomes active as soon as it + is created, you should not create an ActionGroup() object before entering + the with statement. Thus, you should always use the following form:: + + with apt_pkg.ActionGroup(depcache): + ... + + For code which has to run on Python versions prior to 2.5, you can also + use the traditional way:: + + actiongroup = apt_pkg.ActionGroup(depcache) + ... + actiongroup.release() + + In addition to the methods required to implement the context + manager interface, :class:`ActionGroup` objects provide the + following method: + + .. method:: release() + + Release the ActionGroup. This will reactive the collection of package + garbage. + +Resolving Dependencies with :class:`ProblemResolver` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. class:: ProblemResolver(depcache: DepCache) + + ProblemResolver objects take care of resolving problems with + dependencies. They mark packages for installation/removal and + try to satisfy all dependencies. The constructor takes a single + argument of the type :class:`apt_pkg.DepCache` to determine the + cache that shall be manipulated in order to resolve the problems. + + .. method:: clear(pkg: Package) + + Revert the action of calling :meth:`protect` or :meth:`remove` on + a package, resetting it to the default state. + + .. method:: install_protect() + + Mark all protected packages for installation. + + .. method:: protect(pkg: Package) + + Mark the package given by *pkg* as protected; that is, its state + will not be changed. + + .. method:: remove(pkg: Package) + + Mark the package given by *pkg* for removal in the resolver. + + .. method:: resolve([fix_broken: bool = True]) -> bool + + Try to intelligently resolve problems by installing and removing + packages. If *fix_broken* is ``True``, apt will try to repair broken + dependencies of installed packages. + + .. method:: resolve_by_keep() -> bool + + Try to resolve the problems without installing or removing packages. + + .. method:: keep_phased_updates() -> bool + + Hold back upgrades to phased versions of already installed + packages, unless they are security updates. + +:class:`Group` of packages with the same name +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. class:: Group(cache: Cache, name: str) + + .. versionadded:: 0.8.0 + + A collection of packages in which all packages have the same name. Groups + are used in multi-arch environments, where two or more packages have the + same name, but different architectures. + + Group objects provide the following parts for sequential access: + + .. describe:: group[index] + + Get the package at the given **index** in the group. + + .. note:: + Groups are internally implemented using a linked list. The object + keeps a pointer to the current object and the first object, so + access to the first element, or accesses in order have a + complexity of O(1). Random-access complexity is ranges from + O(1) to O(n). + + Group objects also provide special methods to find single packages: + + .. method:: find_package(architecture: str) -> Package + + Find a package with the groups name and the architecture given + in the argument *architecture*. If no such package exists, return + ``None``. + + .. method:: find_preferred_package(prefer_nonvirtual: bool = True) -> Package + + Find the preferred package. This is the package of the native + architecture (specified in ``APT::Architecture``) if available, + or the package from the first foreign architecture. If no package + could be found, return ``None`` + + If **prefer_nonvirtual** is ``True``, the preferred package + will be a non-virtual package, if one exists. + + +:class:`Package` information +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. class:: Package + + Represent a package. A package is uniquely identified by its name and + architecture and each package can have zero or more versions which can be + accessed via the :attr:`version_list` property. Packages can be + installed and removed by a :class:`DepCache` object. + + Attributes: + + .. attribute: architecture + + The architecture of the package. This is relevant on multi-arch + systems only. Please note that if a package is Architecture: all, + this value is not "all", but the architecture of the package file + it comes from. + + .. versionadded:: 0.7.100.3 + + .. attribute:: current_ver + + The version currently installed as a :class:`Version` object, or None + if the package is not installed. + + .. method:: get_fullname([pretty: bool = False]) -> str + + Get the full name of the package, including the architecture. If + *pretty* is ``True``, the architecture is omitted for native packages, + that is, an amd64 "apt" package on an amd64 system would give "apt". + + .. versionadded:: 0.7.100.3 + + .. attribute:: has_provides + + A boolean value determining whether the list available via the + attribute :attr:`provides_list` has at least one element. This + value may be used in combination with :attr:`has_versions` to + check whether a package is virtual; that is, it has no versions + and is provided at least once:: + + pkg.has_provides and not pkg.has_versions + + .. attribute:: has_versions + + A boolean value determining whether the list available via the + attribute :attr:`version_list` has at least one element. This + value may be used in combination with :attr:`has_provides` to + check whether a package is virtual; that is, it has no versions + and is provided at least once:: + + pkg.has_provides and not pkg.has_versions + + .. attribute:: id + + The ID of the package. This can be used to store information about + the package. The ID is an int value. + + .. attribute:: name + + This is the name of the package. + + .. attribute:: provides_list + + A list of all package versions providing this package. Each element + of the list is a triplet, where the first element is the name of the + provided package, the second element the provided version (empty + string), and the third element the version providing this package + as a :class:`Version` object. + + .. attribute:: rev_depends_list + + An iterator of :class:`Dependency` objects for dependencies on this + package. The returned iterator is implemented by the class + :class:`DependencyList`: + + .. class:: DependencyList + + A simple list-like type for representing multiple dependency + objects in an efficient manner; without having to generate + all Dependency objects in advance. + + .. describe:: list[index] + + Return the item at the position *index* in the list. + + .. method:: __len__() + + The length of the list. This method should not be used + irectly, instead Python's built-in function :func:`len` + should be used. + + .. attribute:: section + + The section of the package, as specified in the record. The list of + possible sections is defined in the Policy. This is a string. + + .. deprecated:: 1.0 + + A package can have multiple versions with different sections, so + the section information should be accessed from the version class. + + .. attribute:: version_list + + A list of :class:`Version` objects for all versions of this package + available in the cache. + + **States**: + + .. attribute:: selected_state + + The state we want it to be, ie. if you mark a package for installation, + this is :attr:`apt_pkg.SELSTATE_INSTALL`. + + See :ref:`SelStates` for a list of available states. + + .. attribute:: inst_state + + The state the currently installed version is in. This is normally + :attr:`apt_pkg.INSTSTATE_OK`, unless the installation failed. + + See :ref:`InstStates` for a list of available states. + + .. attribute:: current_state + + The current state of the package (not installed, unpacked, installed, + etc). See :ref:`CurStates` for a list of available states. + + **Flags**: + + .. attribute:: essential + + Whether the package has the 'Essential' flag set; that is, + whether it has a field 'Essential: yes' in its record. + + .. attribute:: important + + Whether the package has the (obsolete) 'Important' flag set; that is, + whether it has a field 'Important: yes' in its record. + +Example: +~~~~~~~~~ +.. literalinclude:: ../examples/cache-packages.py + + + +:class:`Version` +^^^^^^^^^^^^^^^^^ +.. class:: Version + + The version object contains all information related to a specific package + version. + + .. attribute:: arch + + The architecture of the package, eg. amd64 or all. + + .. attribute:: depends_list + + This is basically the same as :attr:`depends_list_str`, + but instead of the ('pkgname', 'version', 'relation') tuples, + it returns :class:`Dependency` objects, which can assist you with + useful functions. + + .. attribute:: depends_list_str + + A dictionary of dependencies. The key specifies the type of the + dependency ('Depends', 'Recommends', etc.). + + The value is a list, containing items which refer to the or-groups of + dependencies. Each of these or-groups is itself a list, containing + tuples like ('pkgname', 'version', 'relation') for each or-choice. + + An example return value for a package with a 'Depends: python (>= 2.4)' + would be:: + + {'Depends': [ + [ + ('python', '2.4', '>=') + ] + ] + } + + The same for a dependency on A (>= 1) | B (>= 2):: + + {'Depends': [ + [ + ('A', '1', '>='), + ('B', '2', '>='), + ] + ] + } + + The comparison operators are not the Debian ones, but the standard + comparison operators as used in languages such as C and Python. This + means that '>' means "larger than" and '<' means "less than". + + .. attribute:: downloadable + + Whether this package can be downloaded from a remote site. + + .. attribute:: file_list + + A list of (:class:`PackageFile`, int: index) tuples for all Package + files containing this version of the package. + + .. attribute:: hash + + An integer hash value used for the internal storage. + + .. attribute:: id + + A numeric identifier which uniquely identifies this version in all + versions in the cache. + + .. attribute:: installed_size + + The size of the package (in kilobytes), when unpacked on the disk. + + .. attribute:: multi_arch + + The multi-arch state of the package. Can be one of the following + attributes. + + .. attribute:: MULTI_ARCH_NO + + No multi-arch + + .. attribute:: MULTI_ARCH_ALL + + An ``Architecture: all`` package + + + .. attribute:: MULTI_ARCH_FOREIGN + + Can satisfy dependencies of foreign-architecture + packages + + .. attribute:: MULTI_ARCH_ALL_FOREIGN + + :attr:`MULTI_ARCH_FOREIGN` for ``Architecture: all`` + packages. + + .. attribute:: MULTI_ARCH_SAME + + Multiple versions from different architectures may be + installed in parallel, but may only satisfy dependencies + of packages from the same architecture + + .. attribute:: MULTI_ARCH_ALLOWED + + Installation in parallel and satisfying ``pkg:any`` + style dependencies is allowed. + + .. attribute:: MULTI_ARCH_ALL_ALLOWED + + :attr:`MULTI_ARCH_ALLOWED` for ``Architecture: all`` + packages. + + + + + .. attribute:: parent_pkg + + The :class:`Package` object this version belongs to. + + .. attribute:: priority + + The integer representation of the priority. This can be used to speed + up comparisons a lot, compared to :attr:`priority_str`. + + The values are defined in the :mod:`apt_pkg` extension, see + :ref:`Priorities` for more information. + + .. attribute:: priority_str + + Return the priority of the package version, as a string, eg. + "optional". + + .. attribute:: provides_list + + This returns a list of all packages provided by this version. Like + :attr:`Package.provides_list`, it returns a list of tuples + of the form ('virtualpkgname', '', :class:`Version`), where as the + last item is the same as the object itself. + + .. attribute:: section + + The usual sections (eg. admin, net, etc.). Prefixed with the component + name for packages not in main (eg. non-free/admin). + + .. attribute:: size + + The size of the .deb file, in bytes. + + .. attribute:: translated_description + + Return a :class:`Description` object for the translated description + of this package version. + + .. attribute:: is_security_update + + Whether this version is a security update. + + .. attribute:: ver_str + + The version, as a string. + + + +:class:`Dependency` +^^^^^^^^^^^^^^^^^^^^ +.. class:: Dependency + + Represent a dependency from one package to another one. + + .. method:: all_targets + + A list of all possible target :class:`Version` objects which satisfy + this dependency. + + .. attribute:: comp_type + + The type of comparison (<,<=,=,!=,>=,>,), as string. Note that the + empty string is a valid string as well, if no version is specified. + + .. attribute:: dep_type + + The type of the dependency, as string, eg. "Depends". + + .. attribute:: dep_type_enum + + The type of the dependency, as an integer which can be compared to + one of the TYPE_* constants below. + + .. attribute:: dep_type_untranslated + + The type of the depndency, as an untranslated string. + + .. attribute:: id + + The ID of the package, as integer. + + .. attribute:: parent_pkg + + The :class:`Package` object of the package which declares the + dependency. This is the same as using ParentVer.ParentPkg. + + .. attribute:: parent_ver + + The :class:`Version` object of the parent version, ie. the package + which declares the dependency. + + .. attribute:: target_pkg + + The :class:`Package` object of the target package. + + .. attribute:: target_ver + + The target version of the dependency, as string. Empty string if the + dependency is not versioned. + + The following constants describe all values the attribute *dep_type_enum* + can take: + + .. attribute:: TYPE_CONFLICTS + + Constant for checking against dep_type_enum + + .. attribute:: TYPE_DEPENDS + + Constant for checking against dep_type_enum + + .. attribute:: TYPE_DPKG_BREAKS + + Constant for checking against dep_type_enum + + .. attribute:: TYPE_ENHANCES + + Constant for checking against dep_type_enum + + .. attribute:: TYPE_OBSOLETES + + Constant for checking against dep_type_enum + + .. attribute:: TYPE_PREDEPENDS + + Constant for checking against dep_type_enum + + .. attribute:: TYPE_RECOMMENDS + + Constant for checking against dep_type_enum + + .. attribute:: TYPE_REPLACES + + Constant for checking against dep_type_enum + + .. attribute:: TYPE_SUGGESTS + + Constant for checking against dep_type_enum + +Example: Find all missing dependencies +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +With the help of Dependency.all_targets(), you can easily find all packages with +broken dependencies: + +.. literalinclude:: ../examples/missing-deps.py + + +:class:`Description` +^^^^^^^^^^^^^^^^^^^^^ +.. class:: Description + + Represent the description of the package. + + .. attribute:: language_code + + The language code of the description; or, if the description + is untranslated, an empty string. + + .. attribute:: md5 + + The MD5 checksum of the description. + + .. attribute:: file_list + + A list of tuples ``(packagefile: PackageFile, index: int)``. + +Package Pinning with :class:`Policy` +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +.. class:: Policy(cache: apt_pkg.Cache) + + Representation of the policy of the :class:`Cache` object given by + *cache*. This provides a superset of policy-related functionality + compared to the *DepCache* class. The DepCache can be used for most + purposes, but there may be some cases where a special policy class + is needed. + + .. method:: create_pin(type: str, pkg: str, data: str, priority: int) + + Create a pin for the policy. The parameter *type* refers to one of the + strings 'Version', 'Release', or 'Origin'. The argument *pkg* is the + name of the package. The parameter *data* refers to the value (such + as 'unstable' for type='Release') and the other possible options. + The parameter 'priority' gives the priority of the pin. + + .. automethod:: init_defaults + + .. method:: get_candidate_ver(package: apt_pkg.Package) -> apt_pkg.Version + + Get the best package for the job; that is, the package with the + highest pin priority. + + .. method:: get_priority(package: Union[apt_pkg.Version, apt_pkg.PackageFile]) -> int + + Get the pin priority of the package, version, or package file + given by *package*. + + .. versionchanged:: 1.7 + + Introduce support for per-version pins. Deprecated support + for :class:`apt_pkg.Package`. + + .. method:: read_pindir(dirname: str) -> bool + + Read the pin files in the given dir (e.g. '/etc/apt/preferences.d') + and add them to the policy. + + .. method:: read_pinfile(filename: str) -> bool + + Read the pin file given by *filename* (e.g. '/etc/apt/preferences') + and add it to the policy. + + +Index Files +------------- + +.. class:: MetaIndex + + Represent a Release file as stored in the cache. + + .. attribute:: uri + + The URI the meta index file is located at, as a string. + + .. attribute:: dist + + The distribution stored in the meta index, as a string. + + .. attribute:: is_trusted + + A boolean value determining whether the meta index can be trusted. This + is ``True`` for signed Release files. + + .. attribute:: index_files + + A list of all :class:`IndexFile` objects associated with this meta + index. + + +.. class:: IndexFile + + Represent an index file, that is, package indexes, translation indexes, + and source indexes. + + .. method:: archive_uri(path: str) -> str + + Return the URI to the given path in the archive. + + .. attribute:: label + + The label of the index file. + + .. attribute:: describe + + A string describing this object. + + .. attribute:: exists + + A boolean value determining whether the index file exists. + + .. attribute:: has_packages + + A boolean value determining whether the index file has packages. + + .. attribute:: size + + The size of the file, measured in bytes. + + .. attribute:: is_trusted + + A boolean value determining whether the file can be trusted; that is, + because it is from a source with a GPG signed Release file. + + + +.. class:: PackageFile + + Provide access to an index file stored in the cache, such as + :file:`/var/lib/dpkg/status`. + + .. attribute:: architecture + + The architecture of the package file. This attribute normally + contains an empty string and is thus not very useful. + + .. attribute:: archive + + The archive of the package file as set in the Release file via + the "Suite" field. If there is no Release file, this is an empty + string. + + .. attribute:: component + + The component of the package file, if it is provided by a repository + using the dists/ hierarchy. For other packages files, this property + is an empty string. + + .. attribute:: filename + + The path to the file on the local filesystem. + + .. attribute:: id + + The ID of the package. This is an integer which can be used to store + further information about the file [eg. as dictionary key]. + + .. attribute:: index_type + + A string describing the type of index. Known values are + "Debian Package Index", "Debian Translation Index", and + "Debian dpkg status file". + + .. attribute:: label + + The label of the package file as set in the release file + via the 'Label' field. If there is no Release file, this + attribute is an empty string. + + .. attribute:: not_automatic + + Whether packages from this list will be updated automatically. The + default for example is False. + + .. attribute:: not_source + + Whether the file has no source from which it can be updated. In such a + case, the value is ``True``; else ``False``. For example, it is + ``False`` for :file:`/var/lib/dpkg/status`. + + Example:: + + for pkgfile in cache.file_list: + if pkgfile.not_source: + print('The file %s has no source.' % pkgfile.filename) + + .. attribute:: origin + + The Origin, as set in the Release file + + .. attribute:: site + + The hostname of the site. + + .. attribute:: size + + The size of the file. + + .. attribute:: version + + The version, as set in the release file (eg. "4.0" for "Etch") + + +The following example shows how to use PackageFile: + +.. literalinclude:: ../examples/cache-pkgfile.py + + +Records (Release files, Packages, Sources) +------------------------------------------ + +.. class:: IndexRecords() + + Represent a Release file and provide means to read information from + the file. This class provides several methods: + + .. method:: get_dist() -> str + + Return the distribution set in the Release file. + + .. method:: load(filename: str) + + Load the file located at the path given by *filename*. + + .. method:: lookup(key: str) -> (HashString, int) + + Look up the filename given by *key* and return a tuple (hash, size), + where the first element *hash* is a :class:`HashString` object + and the second element *size* is an int object. + + +.. class:: PackageRecords(cache: apt_pkg.Cache) + + Provide further information about the packages in the :class:`Cache` object + *cache*. This efficiently parses the package files to provide information + not available in the cache, such as maintainer, hash sums, description, + and the file name of the package. It also provides the complete record + of the package. + + .. method:: lookup(verfile_iter: (PackageFile, int)) -> bool + + Change the actual package to the package given by the verfile_iter. + + The parameter *verfile_iter* refers to a tuple consisting + of (:class:`PackageFile()`, int: index), as returned by various + ``file_list`` attributes such as :attr:`Version.file_list`. + + Example (shortened):: + + cand = depcache.get_candidate_ver(cache['python-apt']) + records.lookup(cand.file_list[0]) + # Now you can access the record + print(records.source_pkg) # == python-apt + + .. describe:: section[key] + + Return the value of the field at *key*. If *key* is not available, + raise :exc:`KeyError`. + Raises AttributeError if not yet looked up. + + .. versionadded:: 1.7 + + .. describe:: key in section + + Return ``True`` if *section* has a key *key*, else ``False``. + Raises AttributeError if not yet looked up. + + .. versionadded:: 1.7 + + .. attribute:: filename + + Return the field 'Filename' of the record. This is the path to the + package, relative to the base path of the archive. + + .. attribute:: hashes + + A :class:`apt_pkg.HashStringList` of all hashes. + + .. versionadded:: 1.1 + + .. attribute:: md5_hash + + Return the MD5 hashsum of the package This refers to the field + 'MD5Sum' in the raw record. + + .. deprecated:: 1.1 + + Use :attr:`hashes` instead. + + .. attribute:: sha1_hash + + Return the SHA1 hashsum of the package. This refers to the field 'SHA1' + in the raw record. + + .. deprecated:: 1.1 + + Use :attr:`hashes` instead. + + .. attribute:: sha256_hash + + Return the SHA256 hashsum of the package. This refers to the field + 'SHA256' in the raw record. + + .. versionadded:: 0.7.9 + + .. deprecated:: 1.1 + + Use :attr:`hashes` instead. + + .. attribute:: source_pkg + + The name of the source package, if different from the name of the + binary package. This information is retrieved from the 'Source' field. + + .. attribute:: source_ver + + The version of the source package, if it differs from the version + of the binary package. Just like 'source_pkg', this information + is retrieved from the 'Source' field. + + .. attribute:: maintainer + + Return the maintainer of the package. + + .. attribute:: short_desc + + Return the short description. This is the summary on the first line of + the 'Description' field. + + .. attribute:: long_desc + + Return the long description. These are lines 2-END from the + 'Description' field. + + .. attribute:: name + + Return the name of the package. This is the 'Package' field. + + .. attribute:: homepage + + Return the Homepage. This is the 'Homepage' field. + + .. attribute:: record + + Return the whole record as a string. If you want to access fields of + the record not available as an attribute, you can use + :class:`apt_pkg.TagSection` to parse the record and access the field + name. + + .. deprecated:: 1.7 + + This property can be considered deprecated for simple string + lookups, as keys can now be looked up in the record itself. + + Example:: + + section = apt_pkg.TagSection(records.record) + print(section['SHA256']) # Use records.sha256_hash instead + +.. class:: SourceRecords + + Provide an easy way to look up the records of source packages and + provide easy attributes for some widely used fields of the record. + + .. note:: + + If the Lookup failed, because no package could be found, no error is + raised. Instead, the attributes listed below are simply not existing + anymore (same applies when no Lookup has been made, or when it has + been restarted). + + .. method:: lookup(pkgname: str) -> bool + + Look up the source package with the given name. Each call moves + the position of the records parser forward. If there are no + more records, return None. If the lookup failed this way, + access to any of the attributes will result in an + :exc:`AttributeError`. + + Imagine a package P with two versions X, Y. The first ``lookup(P)`` + would set the record to version X and the second ``lookup(P)`` to + version Y. A third call would return ``None`` and access to any + of the below attributes will result in an :exc:`AttributeError` + + .. method:: restart() + + Restart the lookup process. This moves the parser to the first + package and lookups can now be made just like on a new object. + + Imagine a package P with two versions X, Y. The first ``Lookup(P)`` + would set the record to version X and the second ``Lookup(P)`` to + version Y. If you now call ``restart()``, the internal position + will be cleared. Now you can call ``lookup(P)`` again to move to X. + + .. attribute:: binaries + + Return a list of strings describing the package names of the binaries + created by the source package. This matches the 'Binary' field in the + raw record. + + .. attribute:: build_depends + + Return a dictionary representing the build-time dependencies of the + package. The format is the same as for :attr:`Version.depends_list_str` + and possible keys being ``"Build-Depends"``, ``"Build-Depends-Indep"``, + ``"Build-Conflicts"`` or ``"Build-Conflicts-Indep"``. + + .. attribute:: files + + The list of files. This returns a list of :class:`SourceRecordsFile` + + .. versionchanged:: 1.6 + + Used to be a list of tuples, see :class:`SourceRecordFile` for the tuple + layout. + + .. attribute:: index + + A list of :class:`IndexFile` objects associated with this + source package record. + + .. attribute:: maintainer + + A string describing the name of the maintainer. + + .. attribute:: package + + The name of the source package. + + .. attribute:: record + + The whole record, as a string. You can use :func:`apt_pkg.ParseSection` + if you need to parse it. You need to parse the record to access + fields not available via the attributes such as 'Standards-Version' + + .. attribute:: section + + A string describing the section. + + .. attribute:: version + + A string describing the version of the source package. + +.. class:: SourceRecordsFile + + Represents a file in a source record. + + .. versionadded:: 1.6 + + Before 1.6, this was a tuple `(md5, size, path, type)`. + + .. attribute:: hashes + + A :class:`HashStringList` of the file's hashes. + + .. attribute:: path + + The path to the file + + .. attribute:: size + + The size of the file + + .. attribute:: type + + The type of the file. Can be 'diff' (includes .debian.tar.gz), 'dsc', or 'tar'. + +The Acquire interface +---------------------- +The Acquire Interface is responsible for all sorts of downloading in apt. All +packages, index files, etc. downloading is done using the Acquire functionality. + +The :mod:`apt_pkg` module provides a subset of this functionality which allows +you to implement file downloading in your applications. Together with the +:class:`PackageManager` class you can also fetch all the packages marked for +installation. + +.. class:: Acquire([progress: apt.progress.base.AcquireProgress]) + + Coordinate the retrieval of files via network or local file system + (using ``copy://path/to/file`` style URIs). Items can be added to + an Acquire object using various means such as creating instances + of :class:`AcquireFile` or the methods :meth:`SourceList.get_indexes` + and :meth:`PackageManager.get_archives`. + + Acquire objects maintain a list of items which will be fetched or have + been fetched already during the lifetime of this object. To add new items + to this list, you can create new :class:`AcquireFile` objects which allow + you to add single files. + + The constructor takes an optional parameter *progress* which takes an + :class:`apt.progress.base.AcquireProgress` object. This object may then + report progress information (see :mod:`apt.progress.text` for reporting + progress to a I/O stream). + + Acquire items have two methods to start and stop the fetching: + + .. method:: run() -> int + + Fetch all the items which have been added by :class:`AcquireFile` and + return one of the constants :attr:`RESULT_CANCELLED`, + :attr:`RESULT_CONTINUE`, :attr:`RESULT_FAILED` to describe the + result of the run. + + .. method:: shutdown() + + Shut the fetcher down. This removes all items from the queue and + makes all :class:`AcquireItem`, :class:`AcquireWorker`, + :class:`AcquireItemDesc` objects useless. Accessing an object of one + of those types can cause a segfault then. + + Removing an item does not mean that the already fetched data will + be removed from the destination. Instead, APT might use the partial + result and continue from thereon. + + Furthermore, they provide three attributes which provide information + on how much data is already available and how much data still needs + to be fetched: + + .. attribute:: fetch_needed + + The amount of data that has to be fetched in order to fetch all + queued items. + + .. attribute:: partial_present + + The amount of data which is already available. + + .. attribute:: total_needed + + The total amount of bytes needed (including those of files which are + already present). + + They also provide two attributes representing the items being processed + and the workers fetching them: + + .. attribute:: items + + A list of :class:`AcquireItem` objects which are attached to the + to this Acquire object. This includes all items ever attached to + this object (except if they were removed using, for example, + :meth:`shutdown()` or by deleting an :class:`AcquireFile` object.) + + .. attribute:: workers + + A list of :class:`AcquireWorker` objects which are currently active + on this instance. + + The Acquire class comes with three constants which represents the results + of the :meth:`run` method: + + .. attribute:: RESULT_CANCELLED + + The fetching has been aborted, e.g. due to a progress class returning + ``False`` in its :meth:`pulse()` method. + + .. attribute:: RESULT_CONTINUE + + All items have been fetched successfully or failed transiently + and the process has not been canceled. + + You need to look at the status of each item and check if it has not + failed transiently to discover errors like a Not Found when acquiring + packages. + + .. attribute:: RESULT_FAILED + + An item failed to fetch due to some reasons. + + +.. class:: AcquireItem + + An AcquireItem object represents a single item of an :class:`Acquire` + object. It is an abstract class to represent various types of items + which are implemented as subclasses. The only exported subclass is + :class:`AcquireFile` which can be used to fetch files. + + .. attribute:: complete + + A boolean value which is True only if the item has been + fetched successfully. + + .. attribute:: desc_uri + + An URI describing where the item is located at. + + .. attribute:: destfile + + The path to the local location where the fetched data will be + stored at. + + .. attribute:: error_text + + The error message. For example, when a file does not exist on a HTTP + server, this will contain a 404 error message. + + .. attribute:: filesize + + The size of the file, in bytes. If the size of the to be fetched file + is unknown, this attribute is set to ``0``. + + .. attribute:: id + + The ID of the item. This attribute is normally set to ``0``, users may + set a custom value here, for instance in an overridden + :meth:`apt.progress.base.AcquireProgress.fetch` method (the progress + class could keep a counter, increase it by one for every :meth:`fetch` + call and assign the current value to this attribute). + + .. attribute:: is_trusted + + A boolean value determining whether the file is trusted. Only ``True`` + if the item represents a package coming from a repository which is + signed by one of the keys in APT's keyring. + + .. attribute:: local + + A boolean value determining whether this file is locally available + (``True``) or whether it has to be fetched from a remote source + (``False``). + + .. attribute:: mode + + Old name for active_subprocess + + .. deprecated:: 1.0 + + .. attribute:: active_subprocess + + The name of the active subprocess (for instance, 'gzip', 'rred' or 'gpgv'). + + .. versionadded:: 1.0 + + **Status**: + + The following attribute represents the status of the item. This class + provides several constants for comparing against this value which are + listed here as well. + + .. attribute:: status + + Integer, representing the status of the item. This attribute can be + compared against the following constants to gain useful information + on the item's status. + + .. attribute:: STAT_AUTH_ERROR + + An authentication error occurred while trying to fetch the item. + + .. attribute:: STAT_DONE + + The item is completely fetched and there have been no problems + while fetching the item. + + .. attribute:: STAT_ERROR + + An error occurred while trying to fetch the item. This error is + normally not related to authentication problems, as thus are + dealt with using :attr:`STAT_AUTH_ERROR`. + + .. attribute:: STAT_FETCHING + + The item is being fetched currently. + + .. attribute:: STAT_IDLE + + The item is yet to be fetched. + + .. attribute:: STAT_TRANSIENT_NETWORK_ERROR + + There was a network error. + + +.. class:: AcquireFile(owner, uri[, hash, size, descr, short_descr, destdir, destfile]) + + Create a new :class:`AcquireFile()` object and register it with *acquire*, + so it will be fetched. You must always keep around a reference to the + object, otherwise it will be removed from the Acquire queue again. + + The parameter *owner* refers to an :class:`Acquire()` object as returned + by :func:`GetAcquire`. The file will be added to the Acquire queue + automatically. + + The parameter *uri* refers to the location of the file, any protocol + of apt is supported. + + The parameter *hash* refers to the hash of the file. If this is set + libapt will check the file after downloading. This should be an instance + of :class:`apt_pkg.HashStringList`. + + The parameter *size* can be used to specify the size of the package, + which can then be used to calculate the progress and validate the download. + + The parameter *descr* is a description of the download. It may be + used to describe the item in the progress class. *short_descr* is the + short form of it. + + The parameters *descr* and *short_descr* can be used to specify + descriptions for the item. The string passed to *descr* should + describe the file and its origin (e.g. "http://localhost sid/main + python-apt 0.7.94.2") and the string passed to *short_descr* should + be one word such as the name of a package. + + Normally, the file will be stored in the current directory using the + file name given in the URI. This directory can be changed by passing + the name of a directory to the *destdir* parameter. It is also possible + to set a path to a file using the *destfile* parameter, but both can + not be specified together. + + In terms of attributes, this class is a subclass of :class:`AcquireItem` + and thus inherits all its attributes. + + .. versionchanged:: 1.9.1 + + The *hash* parameter now accepts an :class:`apt_pkg.HashStringList`, + the old *md5* parameter has been removed. + +.. class:: AcquireWorker + + An :class:`AcquireWorker` object represents a sub-process responsible for + fetching files from remote locations. There is no possibility to create + instances of this class from within Python, but a list of objects of + currently active workers is provided by :attr:`Acquire.workers`. + + Objects of this type provide several attributes which give information + about the worker's current activity. + + .. attribute:: current_item + + The item which is currently being fetched. This returns an + :class:`AcquireItemDesc` object. + + .. attribute:: current_size + + How many bytes of the file have been downloaded. Zero if the current + progress of the file cannot be determined. + + .. attribute:: resumepoint + + The amount of data which was already available when the download was + started. + + .. attribute:: status + + The most recent (localized) status string received from the + sub-process. + + .. attribute:: total_size + + The total number of bytes to be downloaded for the item. Zero if the + total size is unknown. + +.. class:: AcquireItemDesc + + An :class:`AcquireItemDesc` object stores information about the item which + can be used to describe the item. Objects of this class are used in the + progress classes, see the :class:`apt.progress.base.AcquireProgress` + documentation for information how. + + .. attribute:: description + + The long description given to the item. + + .. attribute:: owner + + The :class:`AcquireItem` object owning this object. + + .. attribute:: shortdesc + + A short description which has been given to this item. + + .. attribute:: uri + + The URI from which this item would be downloaded. + + +Hashes +------ +The apt_pkg module also provides several hash functions. If you develop +applications with python-apt it is often easier to use these functions instead +of the ones provides in Python's :mod:`hashlib` module. + +The module provides the two classes :class:`Hashes` and :class:`HashString` for +generic hash support: + +.. autoclass:: Hashes + :members: + +.. class:: HashString(type: str[, hash: str]) + + HashString objects store the type of a hash and the corresponding hash. + They are used by e.g :meth:`IndexRecords.lookup`. The first parameter, + *type* refers to one of "MD5Sum", "SHA1" and "SHA256". The second parameter + *hash* is the corresponding hash. + + You can also use a combined form by passing a string with type and hash + separated by a colon as the only argument. For example:: + + HashString("MD5Sum:d41d8cd98f00b204e9800998ecf8427e") + + + .. describe:: str(hashstring) + + Convert the HashString to a string by joining the hash type and the + hash using ':', e.g. ``"MD5Sum:d41d8cd98f00b204e9800998ecf8427e"``. + + .. attribute:: hashtype + + The type of the hash, as a string. This may be "MD5Sum", "SHA1", + "SHA256" or "SHA512". + + .. autoattribute:: hashvalue + + .. autoattribute:: usable + + .. method:: verify_file(filename: str) -> bool + + Verify that the file given by the parameter *filename* matches the + hash stored in this object. + +.. autoclass:: HashStringList + :members: + + .. describe:: len(list) + + Return the length of the list + + .. describe:: list[index] + + Get the :class:`HashString` object at the specified index. + +The :mod:`apt_pkg` module also provides the functions :func:`md5sum`, +:func:`sha1sum` and :func:`sha256sum` for creating a single hash from a +:class:`bytes` or :class:`file` object: + +.. function:: md5sum(object) + + Return the md5sum of the object. *object* may either be a string, in + which case the md5sum of the string is returned, or a :class:`file()` + object (or a file descriptor), in which case the md5sum of its contents is + returned. + + .. versionchanged:: 0.7.100 + Added support for using file descriptors. + + .. deprecated:: 1.9 + + Use :class:`apt_pkg.Hashes` instead. This function will be removed + in a later release. + +.. function:: sha1sum(object) + + Return the sha1sum of the object. *object* may either be a string, in + which case the sha1sum of the string is returned, or a :class:`file()` + object (or a file descriptor), in which case the sha1sum of its contents + is returned. + + .. versionchanged:: 0.7.100 + Added support for using file descriptors. + + .. deprecated:: 1.9 + + Use :class:`apt_pkg.Hashes` instead. This function will be removed + in a later release. + +.. function:: sha256sum(object) + + Return the sha256sum of the object. *object* may either be a string, in + which case the sha256sum of the string is returned, or a :class:`file()` + object (or a file descriptor), in which case the sha256sum of its contents + is returned. + + .. versionchanged:: 0.7.100 + Added support for using file descriptors. + + .. deprecated:: 1.9 + + Use :class:`apt_pkg.Hashes` instead. This function will be removed + in a later release. + +Debian control files +-------------------- +Debian control files are files containing multiple stanzas of :RFC:`822`-style +header sections. They are widely used in the Debian community, and can represent +many kinds of information. One example for such a file is the +:file:`/var/lib/dpkg/status` file which contains a list of the currently +installed packages. + +The :mod:`apt_pkg` module provides two classes to read those files and parts +thereof and provides a function :func:`RewriteSection` which takes a +:class:`TagSection()` object and sorting information and outputs a sorted +section as a string. + +.. class:: TagFile(file, bytes: bool = False) + + An object which represents a typical debian control file. Can be used for + Packages, Sources, control, Release, etc. + + The *file* argument shall be a path name or an open file object. The + argument *bytes* specifies whether the file shall be represented using + bytes (``True``) or unicode (``False``) strings. + + It is a context manager that can be used with a with statement or the + :meth:`close` method. + + .. describe:: with TagFile(...) as ...: + + Use the :class:`TagFile` as a context manager. This will automatically + close the file after the body finished execution. + + .. versionadded:: 1.0 + + .. method:: close() + + Close the file. It's recommended to use the context manager + instead (that is, the `with` statement). + + .. versionadded:: 1.0 + + It provides two kinds of API which should not be used together: + + The first API implements the iterator protocol and should be used whenever + possible because it has less side effects than the other one. It may be + used e.g. with a for loop:: + + with apt_pkg.TagFile('/var/lib/dpkg/status') as tagfile: + for section in tagfile: + print(section['Package']) + + .. versionchanged:: 0.7.100 + Added support for using gzip files, via :class:`gzip.GzipFile` or any + file containing a compressed gzip stream. + + .. versionadded:: 0.8.5 + + Added support for using bytes instead of str in Python 3 + + .. method:: next() + + A TagFile is its own iterator. This method is part of the iterator + protocol and returns a :class:`TagSection` object for the next + section in the file. If there is no further section, this method + raises the :exc:`StopIteration` exception. + + From Python 3 on, this method is not available anymore, and the + global function ``next()`` replaces it. + + The second API uses a shared :class:`TagSection` object which is exposed + through the :attr:`section` attribute. This object is modified by calls + to :meth:`step` and :meth:`jump`. This API provides more control and may + use less memory, but is not recommended because it works by modifying + one object. It can be used like this:: + + with apt_pkg.TagFile('/var/lib/dpkg/status') as tagf: + tagf.step() + print tagf.section['Package'] + + .. method:: step() -> bool + + Step forward to the next section. This simply returns ``True`` if OK, + and ``False`` if there is no section. + + .. method:: offset() -> int + + Return the current offset (in bytes) from the beginning of the file. + + .. method:: jump(offset) -> bool + + Jump back/forward to *offset*. Use ``jump(0)`` to jump to the + beginning of the file again. Returns ``True`` if a section could + be parsed or ``False`` if not. + + .. attribute:: section + + This is the current :class:`TagSection()` instance. + +.. class:: TagSection(text) + + Represent a single section of a debian control file. + + .. describe:: section[key] + + Return the value of the field at *key*. If *key* is not available, + raise :exc:`KeyError`. + + .. describe:: key in section + + Return ``True`` if *section* has a key *key*, else ``False``. + + .. versionadded:: 0.7.100 + + .. method:: bytes() -> int + + The number of bytes in the section. + + .. method:: find(key: str, default: str = '') -> str + + Return the value of the field at the key *key* if available, + else return *default*. + + .. method:: find_flag(key: str) -> bool + + Find a yes/no value for the key *key*. An example for such a + field is 'Essential'. + + .. method:: find_raw(key: str, default: str = '') -> str + + Similar to :meth:`find`, but instead of returning just the value, + it returns the complete field consisting of 'key: value'. + + .. method:: get(key: str, default: str = '') + + Return the value of the field at the key *key* if available, else + return *default*. + + .. method:: keys() + + Return a list of keys in the section. + + + .. automethod:: write + + +A function can be rewritten by using tag classes: + +.. autoclass:: Tag + :members: + + The following static members can be used to determine the meaning of + :attr:`action`: + + .. data:: REWRITE + + Change the field value to the value of :attr:`data` + + .. data:: RENAME + + Rename the tag to a new tag stored in :attr:`data`. + + .. data:: REMOVE + + Remove the tag. + + Apart from this, the class provides access to several attributes. + +.. autoclass:: TagRewrite + +.. autoclass:: TagRemove + +.. autoclass:: TagRename + +Pre-defined ordering for tag sections are: + +.. data:: REWRITE_PACKAGE_ORDER + + The order in which the information for binary packages should be rewritten, + i.e. the order in which the fields should appear. + +.. data:: REWRITE_SOURCE_ORDER + + The order in which the information for source packages should be rewritten, + i.e. the order in which the fields should appear. + + +Dependencies +------------ +.. function:: check_dep(pkgver: str, op: str, depver: str) -> bool + + Check that the given requirement is fulfilled; that is, that the version + string given by *pkg_ver* matches the version string *dep_ver* under + the condition specified by the operator 'dep_op' (<,<=,=,>=,>). + + Return True if *pkg_ver* matches *dep_ver* under the condition 'dep_op'; + for example:: + + >>> apt_pkg.check_dep("1.0", ">=", "1") + True + +The following two functions provide the ability to parse dependencies. They +use the same format as :attr:`Version.depends_list_str`. + +.. function:: parse_depends(depends, strip_multiarch=True, architecture) + + Parse the string *depends* which contains dependency information as + specified in Debian Policy, Section 7.1. + + Returns a list. The members of this list are lists themselves and contain + one or more tuples in the format ``(package,version,operation)`` for every + 'or'-option given, e.g.:: + + >>> apt_pkg.parse_depends("PkgA (>= VerA) | PkgB (>= VerB)") + [[('PkgA', 'VerA', '>='), ('PkgB', 'VerB', '>=')]] + + Note that multiarch dependency information is stripped off by default. + You can force the full dependency info (including the multiarch info) + by passing "False" as a additional parameter to this function. + + You can specify an optional argument *architecture* that treats the given + architecture as the native architecture for purposes of parsing the + dependency. + + .. note:: + + The behavior of this function is different than the behavior of the + old function :func:`ParseDepends()`, because the third field + ``operation`` uses `>` instead of `>>` and `<` instead of `<<` which + is specified in control files. + + +.. function:: parse_src_depends(depends, strip_multiarch=True, architecture) + + Parse the string *depends* which contains dependency information as + specified in Debian Policy, Section 7.1. + + Returns a list. The members of this list are lists themselves and contain + one or more tuples in the format ``(package,version,operation)`` for every + 'or'-option given, e.g.:: + + >>> apt_pkg.parse_depends("PkgA (>= VerA) | PkgB (>= VerB)") + [[('PkgA', 'VerA', '>='), ('PkgB', 'VerB', '>=')]] + + + Furthemore, this function also supports to limit the architectures, as + used in e.g. Build-Depends:: + + >>> apt_pkg.parse_src_depends("a (>= 01) [i386 amd64]") + [[('a', '01', '>=')]] + + Note that multiarch dependency information is stripped off by default. + You can force the full dependency info (including the multiarch info) + by passing "False" as a additional parameter to this function. + + You can specify an optional argument *architecture* that treats the given + architecture as the native architecture for purposes of parsing the + dependency. + + .. note:: + + The behavior of this function is different than the behavior of the + old function :func:`ParseDepends()`, because the third field + ``operation`` uses `>` instead of `>>` and `<` instead of `<<` which + is specified in control files. + + +Configuration and Command-line parsing +-------------------------------------- + +.. class:: Configuration() + + Provide access to and manipulation of APT's configuration which is + used by many classes and functions in this module to define their + behavior. There are options to install recommends, change the root + directory and much more. For an (incomplete) list of available options, + see the :manpage:`apt.conf(5)` manual page. + + The most important Configuration object is the one available by the + module's :attr:`apt_pkg.config` attribute. It stores the global + configuration which affects the behavior of most functions and is + initialized by a call to the function :func:`init_config`. While + possible, it is generally not needed to create other instances of + this class. + + For accessing and manipulating the configuration space, objects + of this type provide an interface which resembles Python mapping + types like :class:`dict`. + + .. describe:: key in conf + + Return ``True`` if *conf* has a key *key*, else ``False``. + + .. describe:: conf[key] + + Return the value of the option given key *key*. If it does not + exist, raise :exc:`KeyError`. + + .. describe:: conf[key] = value + + Set the option at *key* to *value*. + + .. describe del conf[key] + + Delete the option with the name *key* in the configuration object + *conf*. + + .. method:: get(key[, default='']) -> str + + Find the value for the given key and return it. If the given key does + not exist, return *default* instead. + + In addition, they provide methods to resemble the interface provided + by the C++ class and some more mapping methods which have been enhanced + to support some more advanced configuration features: + + .. method:: clear(key: str) + + Remove the option at *key* and all of its children. + + .. method:: dump() -> str + + Return a string containing the values in the configuration object, + in the standard :manpage:`apt.conf(5)` format. + + .. versionadded:: 0.7.100 + + .. method:: exists(key) + + Check whether an option named *key* exists in the configuration. + + .. method:: find(key[, default='']) -> str + + Return the value stored at the option named *key*, or the value + given by the string *default* if the option in question is not + set. + + .. method:: find_b(key[, default=False]) -> bool + + Return the boolean value stored at *key*, or the value given by + the :class:`bool` object *default* if the requested option is + not set. + + .. method:: find_file(key[, default='']) -> str + find_dir(key[, default='/']) -> str + + Locate the given key using :meth:`find` and return the path to the + file/directory. This uses a special algorithms which moves upwards + in the configuration space and prepends the values of the options + to the result. These methods are generally used for the options + stored in the 'Dir' section of the configuration. + + As an example of how this works, take a look at the following options + and their values: + + .. table:: + + ============== =========================== + Option Value + ============== =========================== + Dir / + Dir::Etc etc/apt/ + Dir::Etc::main apt.conf + ============== =========================== + + A call to :meth:`find_file` would now return ``/etc/apt/apt.conf`` + because it prepends the values of "Dir::Etc" and "Dir" to the value + of "Dir::Etc::main":: + + >>> apt_pkg.config.find_file("Dir::Etc::main") + '/etc/apt/apt.conf' + + If the special configuration variable "RootDir" is set, this value + would be prepended to every return value, even if the path is already + absolute. If not, the function ends as soon as an absolute path is + created (once an option with a value starting with "/" is read). + + The method :meth:`find_dir` does exactly the same thing as + :meth:`find_file`, but adds a trailing forward slash before + returning the value. + + .. method:: find_i(key[, default=0]) -> int + + Return the integer value stored at *key*, or the value given by + the integer *default* if the requested option is not set. + + .. method:: keys([key]) + + Return a recursive list of all configuration options or, if *key* + is given, a list of all its children. This method is comparable + to the **keys** method of a mapping object, but additionally + provides the parameter *key*. + + .. method:: list([key]) + + Return a non-recursive list of all configuration options. If *key* + is not given, this returns a list of options like "Apt", "Dir", and + similar. If *key* is given, a list of the names of its child options + will be returned instead. + + .. method:: my_tag() + + Return the tag name of the current tree. Normally (for + :data:`apt_pkg.config`) this is an empty string, but for + sub-trees it is the key of the sub-tree. + + .. method:: set(key: str, value: str) + + Set the option named *key* to the value given by the argument + *value*. It is possible to store objects of the types :class:`int` + and :class:`bool` by calling :func:`str` on them to convert them + to a string object. They can then be retrieved again by using the + methods :meth:`find_i` or :meth:`find_b`. + + .. method:: subtree(key) + + Return a new apt_pkg.Configuration object which starts at the + given option. Example:: + + apttree = config.subtree('APT') + apttree['Install-Suggests'] = config['APT::Install-Suggests'] + + The configuration space is shared with the main object which means + that all modifications in one object appear in the other one as + well. + + .. method:: value_list([key]) + + This is the opposite of the :meth:`list` method in that it returns the + values instead of the option names. + +.. data:: config + + This variable contains the global configuration which is used by + all classes and functions in this module. After importing the + module, this object should be initialized by calling the module's + :func:`init_config` function. + +.. function:: read_config_file(configuration: Configuration, filename: str) + + Read the configuration file *filename* and set the appropriate + options in the configuration object *configuration*. + +.. function:: read_config_dir(configuration, dirname) + + Read all configuration files in the dir given by 'dirname' in the + correct order. + + +.. function:: read_config_file_isc(configuration, filename) + + Read the configuration file *filename* and set the appropriate + options in the configuration object *configuration*. This function + requires a slightly different format than APT configuration files, + if you are unsure, do not use it. + +.. function:: parse_commandline(configuration, options, argv) + + Parse the command line in *argv* into the configuration space. The + list *options* contains a list of 3-tuples or 4-tuples in the form:: + + (short_option: str, long_option: str, variable: str[, type: str]) + + The element *short_option* is one character, the *long_option* element + is the name of the long option, the element *variable* the name of the + configuration option the result will be stored in and *type* is one of + 'HasArg', 'IntLevel', 'Boolean', 'InvBoolean', 'ConfigFile', + 'ArbItem'. The default type is 'Boolean'. + + .. table:: Overview of all possible types + + =========== ===================================================== + Type What happens if the option is given + =========== ===================================================== + HasArg The argument given to the option is stored in + the target. + IntLevel The integer value in the target is increased by one + Boolean The target variable is set to True. + InvBoolean The target variable is set to False. + ConfigFile The file given as an argument to this option is read + in and all configuration options are added to the + configuration object (APT's '-c' option). + ArbItem The option takes an argument *key*=*value*, and the + configuration option at *key* is set to the value + *value* (APT's '-o' option). + =========== ===================================================== + + +Locking +-------- +When working on the global cache, it is important to lock the cache so other +programs do not modify it. This module provides two context managers for +locking the package system or file-based locking. + +.. class:: SystemLock + + Context manager for locking the package system. The lock is established + as soon as the method __enter__() is called. It is released when + __exit__() is called. If the lock can not be acquired or can not be + released an exception is raised. + + This should be used via the 'with' statement. For example:: + + with apt_pkg.SystemLock(): + ... # Do your stuff here. + ... # Now it's unlocked again + + Once the block is left, the lock is released automatically. The object + can be used multiple times:: + + lock = apt_pkg.SystemLock() + with lock: + ... + with lock: + ... + +.. class:: FileLock(filename: str) + + Context manager for locking using a file. The lock is established + as soon as the method __enter__() is called. It is released when + __exit__() is called. If the lock can not be acquired or can not be + released, an exception is raised. + + This should be used via the 'with' statement. For example:: + + with apt_pkg.FileLock(filename): + ... + + Once the block is left, the lock is released automatically. The object + can be used multiple times:: + + lock = apt_pkg.FileLock(filename) + with lock: + ... + with lock: + ... + +For Python versions prior to 2.5, similar functionality is provided by the +following three functions: + +.. function:: get_lock(filename: str, errors=False) -> int + + Create an empty file at the path specified by the parameter *filename* and + lock it. If this fails and *errors* is **True**, the function raises an + error. If *errors* is **False**, the function returns -1. + + The lock can be acquired multiple times within the same process, and can be + released by calling :func:`os.close` on the return value which is the file + descriptor of the created file. + +.. function:: pkgsystem_lock() + + Lock the global pkgsystem. The lock should be released by calling + :func:`pkgsystem_unlock` again. If this function is called n-times, the + :func:`pkgsystem_unlock` function must be called n-times as well to release + all acquired locks. + +.. function:: pkgsystem_unlock() + + Unlock the global pkgsystem. This reverts the effect of + :func:`pkgsystem_lock`. + +Since version 1.7, APT switches to the frontend locking approach where +dpkg has two lock files, :file:`lock-frontend` and :file:`lock`, the +latter being called the inner lock in apt. +When running dpkg, the inner lock must be released before calling dpkg +and reacquired afterwards. When not using APT functions to run dpkg, +the variable `DPKG_FRONTEND_LOCKED` must be set to tell dpkg to not +acquire the :file:`lock-frontend` lock. +These functions usually do not need to be used by external code. + +.. function:: pkgsystem_unlock_inner() + + Release the :file:`lock` lock file to allow dpkg to be run. + + .. versionadded:: 1.7 + +.. function:: pkgsystem_lock_inner() + + Release the :file:`lock` lock file after a dpkg run. + + .. versionadded:: 1.7 + +.. function:: pkgsystem_is_locked() + + Returns true if the global lock is hold. Can be used to check whether + :meth:`pkgsystem_unlock_inner` needs to be called. + + .. versionadded:: 1.7 + + + +Other classes +-------------- +.. class:: Cdrom() + + A Cdrom object identifies Debian installation media and adds them to + :file:`/etc/apt/sources.list`. The C++ version of this class is used by + the apt-cdrom tool and using this class, you can re-implement apt-cdrom + in Python, see :doc:`../tutorials/apt-cdrom`. + + The class :class:`apt.cdrom.Cdrom` is a subclass of this class and + provides some additional functionality for higher level use and some + shortcuts for setting some related configuration options. + + This class provides two functions which take an instance of + :class:`apt.progress.base.CdromProgress` as their argument. + + .. method:: add(progress: apt.progress.base.CdromProgress) -> bool + + Search for a Debian installation media and add it to the list of + sources stored in :file:`/etc/apt/sources.list`. On success, the + boolean value ``True`` is returned. If the process failed or was + canceled by the progress class, :exc:`SystemError` is raised or + ``False`` is returned. + + .. method:: ident(progress: apt.progress.base.CdromProgress) -> str + + Identify the installation media and return a string which describes + its identity. If no media could be identified, :exc:`SystemError` is + raised or ``None`` is returned. + +.. class:: SourceList + + Represent the list of sources stored in files such as + :file:`/etc/apt/sources.list`. + + .. method:: find_index(pkgfile: PackageFile) -> IndexFile + + Return the :class:`IndexFile` object for the :class:`PackageFile` + object given by the argument *pkgfile*. If no index could be found, + return ``None``. + + .. method:: get_indexes(acquire: Acquire[, all: bool = False]) -> bool + + Add all indexes to the :class:`Acquire` object given by the argument + *acquire*. If *all* is ``True``, all indexes will be added, otherwise + only the meta indexes (Release files) will be added and others are + fetched as needed. + + .. method:: read_main_list() -> bool + + Read the files configured in Dir::Etc::SourceList and + Dir::Etc::sourceparts; that is (on normal system), + :file:`/etc/apt/sources.list` and the files in + :file:`/etc/apt/sources.list.d`. + + .. attribute:: list + + A list of :class:`MetaIndex` objects. + +String functions +---------------- +.. function:: base64_encode(value: bytes) -> str + + Encode the given bytes string (which may not contain a null byte) + using base64, for example, on Python 3 and newer:: + + >>> apt_pkg.base64_encode(b"A") + 'QQ==' + + on Python versions prior to 3, the 'b' before the string has to be + omitted. + +.. function:: check_domain_list(host, list) + + See if the host name given by *host* is one of the domains given in the + comma-separated list *list* or a subdomain of one of them. + + >>> apt_pkg.check_domain_list("alioth.debian.org","debian.net,debian.org") + True + +.. function:: dequote_string(string: str) + + Dequote the string specified by the parameter *string*, e.g.:: + + >>> apt_pkg.dequote_string("%61%70%74%20is%20cool") + 'apt is cool' + +.. function:: quote_string(string, repl) + + Escape the string *string*, replacing any character not allowed in a URL + or specified by *repl* with its ASCII value preceded by a percent sign + (so for example ' ' becomes '%20'). + + >>> apt_pkg.quote_string("apt is cool","apt") + '%61%70%74%20is%20cool' + +.. function:: size_to_str(size: int) + + Return a string describing the size in a human-readable manner using + SI prefix and base-10 units, e.g. '1k' for 1000, '1M' for 1000000, etc. + + Example:: + + >>> apt_pkg.size_to_str(10000) + '10.0k' + +.. function:: string_to_bool(input) + + Parse the string *input* and return one of **-1**, **0**, **1**. + + .. table:: Return values + + ===== ============================================= + Value Meaning + ===== ============================================= + -1 The string *input* is not recognized. + 0 The string *input* evaluates to **False**. + +1 The string *input* evaluates to **True**. + ===== ============================================= + + Example:: + + >>> apt_pkg.string_to_bool("yes") + 1 + >>> apt_pkg.string_to_bool("no") + 0 + >>> apt_pkg.string_to_bool("not-recognized") + -1 + + +.. function:: str_to_time(rfc_time) + + Convert the :rfc:`1123` conforming string *rfc_time* to the unix time, and + return the integer. This is the opposite of :func:`TimeRFC1123`. + + Example:: + + >> apt_pkg.str_to_time('Thu, 01 Jan 1970 00:00:00 GMT') + 0 + +.. function:: time_rfc1123(seconds: int) -> str + + Format the unix time specified by the integer *seconds*, according to the + requirements of :rfc:`1123`. + + Example:: + + >>> apt_pkg.time_rfc1123(0) + 'Thu, 01 Jan 1970 00:00:00 GMT' + + +.. function:: time_to_str(seconds: int) -> str + + Format a given duration in a human-readable manner. The parameter *seconds* + refers to a number of seconds, given as an integer. The return value is a + string with a unit like 's' for seconds. + + Example:: + + >>> apt_pkg.time_to_str(3601) + '1h0min1s' + +.. function:: upstream_version(version: str) -> str + + Return the upstream version for the Debian package version given by + *version*. + +.. function:: uri_to_filename(uri: str) -> str + + Take a string *uri* as parameter and return a filename which can be used to + store the file, based on the URI. + + Example:: + + >>> apt_pkg.uri_to_filename('http://debian.org/index.html') + 'debian.org_index.html' + + +.. function:: version_compare(a: str, b: str) -> int + + Compare two versions, *a* and *b*, and return an integer value which has + the same meaning as the built-in :func:`cmp` function's return value has, + see the following table for details. + + .. table:: Return values + + ===== ============================================= + Value Meaning + ===== ============================================= + > 0 The version *a* is greater than version *b*. + = 0 Both versions are equal. + < 0 The version *a* is less than version *b*. + ===== ============================================= + + +Module Constants +---------------- +.. _CurStates: + +Package States +^^^^^^^^^^^^^^^ +.. data:: CURSTATE_CONFIG_FILES + + Only the configuration files of the package exist on the system. + +.. data:: CURSTATE_HALF_CONFIGURED + + The package is unpacked and configuration has been started, but not + yet completed. + +.. data:: CURSTATE_HALF_INSTALLED + + The installation of the package has been started, but not completed. + +.. data:: CURSTATE_INSTALLED + + The package is unpacked, configured and OK. + +.. data:: CURSTATE_NOT_INSTALLED + + The package is not installed. + +.. data:: CURSTATE_UNPACKED + + The package is unpacked, but not configured. + +.. _InstStates: + +Installed states +^^^^^^^^^^^^^^^^ +.. data:: INSTSTATE_HOLD + + The package is put on hold. + +.. data:: INSTSTATE_HOLD_REINSTREQ + + The package is put on hold, but broken and has to be reinstalled. + +.. data:: INSTSTATE_OK + + The package is OK. + +.. data:: INSTSTATE_REINSTREQ + + The package is broken and has to be reinstalled. + +.. _Priorities: + +Priorities +^^^^^^^^^^^ +.. data:: PRI_EXTRA + + The integer representation of the priority 'extra'. + +.. data:: PRI_IMPORTANT + + The integer representation of the priority 'important'. + +.. data:: PRI_OPTIONAL + + The integer representation of the priority 'optional'. + +.. data:: PRI_REQUIRED + + The integer representation of the priority 'required'. + +.. data:: PRI_STANDARD + + The integer representation of the priority 'standard'. + + +.. _SelStates: + +Package selection states +^^^^^^^^^^^^^^^^^^^^^^^^ +.. data:: SELSTATE_DEINSTALL + + The package is selected for deinstallation. + +.. data:: SELSTATE_HOLD + + The package is marked to be on hold and will not be modified. + +.. data:: SELSTATE_INSTALL + + The package is selected for installation. + +.. data:: SELSTATE_PURGE + + The package is selected to be purged. + +.. data:: SELSTATE_UNKNOWN + + The package is in an unknown state. + + +Build information +^^^^^^^^^^^^^^^^^ +.. data:: DATE + + The date on which this extension has been compiled. + +.. data:: LIB_VERSION + + The version of the apt_pkg library. This is **not** the version of apt, + nor the version of python-apt. + +.. data:: TIME + + The time this extension has been built. + +.. data:: VERSION + + The version of apt (not of python-apt). diff --git a/doc/source/library/aptsources.distinfo.rst b/doc/source/library/aptsources.distinfo.rst new file mode 100644 index 0000000..033ef48 --- /dev/null +++ b/doc/source/library/aptsources.distinfo.rst @@ -0,0 +1,11 @@ +:mod:`aptsources.distinfo` --- provide meta information for distro repositories +=============================================================================== +.. note:: + + This part of the documentation is created automatically. + + +.. automodule:: aptsources.distinfo + :members: + :undoc-members: + diff --git a/doc/source/library/aptsources.distro.rst b/doc/source/library/aptsources.distro.rst new file mode 100644 index 0000000..6ebe438 --- /dev/null +++ b/doc/source/library/aptsources.distro.rst @@ -0,0 +1,11 @@ +:mod:`aptsources.distro` --- Distribution abstraction of the sources.list +=============================================================================== +.. note:: + + This part of the documentation is created automatically. + + +.. automodule:: aptsources.distro + :members: + :undoc-members: + diff --git a/doc/source/library/aptsources.sourceslist.rst b/doc/source/library/aptsources.sourceslist.rst new file mode 100644 index 0000000..79b8dd0 --- /dev/null +++ b/doc/source/library/aptsources.sourceslist.rst @@ -0,0 +1,11 @@ +:mod:`aptsources.sourceslist` --- Provide an abstraction of the sources.list +============================================================================ +.. note:: + + This part of the documentation is created automatically. + + +.. automodule:: aptsources.sourceslist + :members: + :undoc-members: + diff --git a/doc/source/library/index.rst b/doc/source/library/index.rst new file mode 100644 index 0000000..0b048c8 --- /dev/null +++ b/doc/source/library/index.rst @@ -0,0 +1,35 @@ +Python APT Library +================== +Python APT's library provides access to almost every functionality supported +by the underlying apt-pkg and apt-inst libraries. This means that it is +possible to rewrite frontend programs like apt-cdrom in Python, and this is +relatively easy, as can be seen in e.g. :doc:`../tutorials/apt-cdrom`. + +When going through the library, the first two modules are :mod:`apt_pkg` and +:mod:`apt_inst`. These modules are more or less straight bindings to the +apt-pkg and apt-inst libraries and the base for the rest of python-apt. + +Going forward, the :mod:`apt` package appears. This package is using +:mod:`apt_pkg` and :mod:`apt_inst` to provide easy to use ways to manipulate +the cache, fetch packages, or install new packages. It also provides useful +progress classes, currently only for text interfaces. The last package is +:mod:`aptsources`. The aptsources package provides classes and functions to +read files like :file:`/etc/apt/sources.list` and to modify them. + +.. toctree:: + :maxdepth: 1 + + apt_pkg + apt_inst + + apt.cache + apt.cdrom + apt.debfile + apt.package + apt.progress.base + apt.progress.text + + aptsources.distinfo + aptsources.distro + aptsources.sourceslist + diff --git a/doc/source/templates/indexcontent.html b/doc/source/templates/indexcontent.html new file mode 100644 index 0000000..be5277e --- /dev/null +++ b/doc/source/templates/indexcontent.html @@ -0,0 +1,50 @@ +{% extends "layout.html" %} +{% block body %} +

{{ docstitle|e }}

+

+ Welcome! This is + {% block description %}the documentation for {{ project|e }} + {{ release|e }}{% if last_updated %}, last updated {{ last_updated|e }}{% endif %}{% endblock %}. +

+ +

+ This documentation has been created using Sphinx and reStructuredText files + written by Julian Andres Klode <jak@debian.org>. +

+ + + + +

Parts of the documentation:

+ + +
+ + + + + + +
+ +

Indices and tables:

+ + +
+ + + + + +
+ +{% endblock %} diff --git a/doc/source/templates/layout.html b/doc/source/templates/layout.html new file mode 100644 index 0000000..04a3e0d --- /dev/null +++ b/doc/source/templates/layout.html @@ -0,0 +1,4 @@ +{% extends "!layout.html" %} +{% block rootrellink %} +
  • {{ shorttitle }}{{ reldelim1 }}
  • +{% endblock %} diff --git a/doc/source/tutorials/apt-cdrom.rst b/doc/source/tutorials/apt-cdrom.rst new file mode 100644 index 0000000..7e1d794 --- /dev/null +++ b/doc/source/tutorials/apt-cdrom.rst @@ -0,0 +1,156 @@ +Writing your own apt-cdrom +========================== +:Author: Julian Andres Klode +:Release: |release| +:Date: |today| + +This article explains how to utilise python-apt to build your own clone of the +:command:`apt-cdrom` command. To do this, we will take a look at the +:mod:`apt.cdrom` and :mod:`apt.progress.text` modules, and we will learn how +to use apt_pkg.parse_commandline to parse commandline arguments. The code shown +here works on Python 2 and Python 3. + +Basics +------ +The first step in building your own :command:`apt-cdrom` clone is to import the +:mod:`apt` package, which will import :mod:`apt.cdrom` and +:mod:`apt.progress.text`:: + + import apt + +Now we have to create a new :class:`apt.cdrom.Cdrom` object and pass to it an +:class:`apt.progress.text.CdromProgress` object, which is responsible for +displaying the progress and asking questions:: + + cdrom = apt.Cdrom(apt.progress.text.CdromProgress()) + +Now we have to choose the action, depending on the given options on the +command line. For now, we simply use the value of ``sys.argv[1]``:: + + import sys + if sys.argv[1] == 'add': + cdrom.add() + elif sys.argv[1] == 'ident': + cdrom.ident() + +Now we have a basic :command:`apt-cdrom` clone which can add and identify +CD-ROMs:: + + import sys + + import apt + + cdrom = apt.Cdrom(apt.progress.text.CdromProgress()) + if sys.argv[1] == 'add': + cdrom.add() + elif sys.argv[1] == 'ident': + cdrom.ident() + +Advanced example with command-line parsing +------------------------------------------- +Our example clearly misses a way to parse the commandline in a correct +manner. Luckily, :mod:`apt_pkg` provides us with a function to do this: +:func:`apt_pkg.parse_commandline`. To use it, we add ``import apt_pkg`` right +after import apt:: + + import sys + + import apt_pkg + import apt + + +:func:`apt_pkg.parse_commandline` is similar to :mod:`getopt` functions, it +takes a list of recognized options and the arguments and returns all unknown +arguments. If it encounters an unknown argument which starts with a leading +'-', the function raises an error indicating that the option is unknown. The +major difference is that this function manipulates the apt configuration space. + +The function takes 3 arguments. The first argument is an +:class:`apt_pkg.Configuration` object. The second argument is a list of tuples +of the form ``(shortopt, longopt, config, type)``, whereas *shortopt* is a +character indicating the short option name, *longopt* a string indicating the +corresponding long option (e.g. ``"--help"``), *config* the name of the +configuration item which should be set and *type* the type of the argument. + +For apt-cdrom, we can use the following statement:: + + arguments = apt_pkg.parse_commandline(apt_pkg.config, + [('h', "help", "help"), + ('v', "version", "version"), + ('d', "cdrom", "Acquire::cdrom::mount", "HasArg"), + ('r', "rename", "APT::CDROM::Rename"), + ('m', "no-mount", "APT::CDROM::NoMount"), + ('f', "fast", "APT::CDROM::Fast"), + ('n', "just-print", "APT::CDROM::NoAct"), + ('n', "recon", "APT::CDROM::NoAct"), + ('n', "no-act", "APT::CDROM::NoAct"), + ('a', "thorough", "APT::CDROM::Thorough"), + ('c', "config-file", "", "ConfigFile"), + ('o', "option", "", "ArbItem")], args) + + +This allows us to support all options supported by apt-cdrom. The first option +is --help. As you can see, it omits the fourth field of the tuple; which means +it is a boolean argument. Afterwards you could use +``apt_pkg.config.find_b("help")`` to see whether ``--help`` was specified. In +``('d',"cdrom","Acquire::cdrom::mount","HasArg")`` the fourth field is +``"HasArg"``. This means that the option has an argument, in this case the +location of the mount point. ``('c',"config-file","","ConfigFile")`` shows how +to include configuration files. This option takes a parameter which points to +a configuration file which will be added to the configuration space. +``('o',"option","","ArbItem")`` is yet another type of option, which allows users +to set configuration options on the commandline. + +Now we have to check whether help or version is specified, and print a message +and exit afterwards. To do this, we use :meth:`apt_pkg.Configuration.find_b` +which returns ``True`` if the configuration option exists and evaluates to +``True``:: + + if apt_pkg.config.find_b("help"): + print("This should be a help message") + sys.exit(0) + elif apt_pkg.config.find_b("version"): + print("Version blah.") + sys.exit(0) + + +Now we are ready to create our progress object and our cdrom object. Instead +of using :class:`apt.Cdrom` like in the first example, we will use +:class:`apt_pkg.Cdrom` which provides a very similar interface. We could also +use :class:`apt.Cdrom`, but `apt.Cdrom` provides options like *nomount* which +conflict with our commandline parsing:: + + progress = apt.progress.text.CdromProgress() + cdrom = apt_pkg.Cdrom() + + +Now we have to do the action requested by the user on the commandline. To see +which option was requested, we check the list ``arguments`` which was returned +by ``apt_pkg.parse_commandline`` above, and afterwards call ``cdrom.add`` or +``cdrom.ident``:: + + if apt_pkg.config.find_b("help"): + print("This should be a help message") + sys.exit(0) + elif apt_pkg.config.find_b("version"): + print("Version blah.") + sys.exit(0) + + if not arguments: + sys.stderr.write('E: No operation specified\n') + sys.exit(1) + elif arguments[0] == 'add': + cdrom.add(progress) + elif arguments[0] == 'ident': + cdrom.ident(progress) + else: + sys.stderr.write('E: Invalid operation %s\n' % arguments[0]) + sys.exit(1) + + +After putting all our actions into a main() function, we get a completely +working apt-cdrom clone, which just misses useful ``--help`` and ``--version`` +options. If we add a function show_help(), we get an even more complete +apt-cdrom clone: + +.. literalinclude:: ../examples/apt-cdrom.py diff --git a/doc/source/tutorials/apt-get.rst b/doc/source/tutorials/apt-get.rst new file mode 100644 index 0000000..26ebc3d --- /dev/null +++ b/doc/source/tutorials/apt-get.rst @@ -0,0 +1,46 @@ +Doing stuff :command:`apt-get` does +=================================== +:Author: Julian Andres Klode +:Release: |release| +:Date: |today| + +The following article will show how you can use python-apt to do actions done +by the :command:`apt-get` command. + + +Printing the URIs of all index files +------------------------------------ +We all now that we can print the URIs of all our index files by running a +simple ``apt-get --print-uris update``. We can do the same. Responsible for +the source entries is the class :class:`apt_pkg.SourceList`, which can be +combined with an :class:`apt_pkg.Acquire` object using :meth:`get_indexes`. + +First of all, we have to create the objects:: + + acquire = apt_pkg.Acquire() + slist = apt_pkg.SourceList() + +Now we have to parse /etc/apt/sources.list and its friends, by using +:meth:`apt_pkg.SourceList.read_main_list`:: + + slist.read_main_list() + +The **slist** object now knows about the location of the indexes. We now have +to load those indexes into the *acquire* object by calling +:meth:`apt_pkg.SourceList.get_indexes`:: + + slist.get_indexes(acquire, True) + +The first argument is the acquire object into which we will load these indexes, +and the second argument means that we want to fetch all indexes. Now the only +thing left to do is iterating over the list of items and printing out their +URIs. Luckily, there is :attr:`apt_pkg.Acquire.items` which allows us to +iterate over the items:: + + for item in acquire.items: + print(item.desc_uri) + +In the end a program could look like this: + +.. literalinclude:: ../examples/update-print-uris.py + diff --git a/doc/source/tutorials/contributing.rst b/doc/source/tutorials/contributing.rst new file mode 100644 index 0000000..33f1654 --- /dev/null +++ b/doc/source/tutorials/contributing.rst @@ -0,0 +1,315 @@ +Contributing to python-apt +========================== +:Author: Julian Andres Klode +:Release: |release| +:Date: |today| + +Let's say you need a new feature, you can develop it, and you want to get it +included in python-apt. Then be sure to follow the following guidelines. + +Available branches +------------------- +First of all, let's talk a bit about the git branches of python-apt. In the +following parts, we will assume that you use git to create your changes and +submit them. + +Repositories +^^^^^^^^^^^^ + +https://salsa.debian.org/apt-team/python-apt.git + + This is the official Debian repository of python-apt. + You can clone it using git by doing:: + + git clone git://salsa.debian.org/apt-team/python-apt.git + + + All code which will be uploaded to Debian is here. + There are also branches for Ubuntu releases, but those may not be up-to-date. + + Branch names consist of the distribution vendor, followed by a slash, + followed by the release of that distribution, for example: ``debian/sid``. + + The current working branch is usually pointed to by ``HEAD``, it is + either ``debian/sid`` or ``debian/experimental``. + + If both sid and experimental are active, bug fixes are either cherry-picked from + ``debian/experimental`` to ``debian/sid``, or a new release is cut on the sid branch + and then merged into experimental. + + Updates to stable release branches, such as ``debian/wheezy``, are almost always + cherry-picked or backported from the ``debian/sid`` branch. + + +.. highlight:: cpp + +C++ Coding style +---------------- +This document gives coding conventions for the C++ code comprising +the C++ extensions of Python APT. Please see the companion +informational PEP describing style guidelines for Python code (:PEP:`8`). + +Note, rules are there to be broken. Two good reasons to break a +particular rule: + + (1) When applying the rule would make the code less readable, even + for someone who is used to reading code that follows the rules. + + (2) To be consistent with surrounding code that also breaks it + (maybe for historic reasons) -- although this is also an + opportunity to clean up someone else's mess (in true XP style). + +This part of the document is derived from :PEP:`7` which was written by +Guido van Rossum. + + +C++ dialect +^^^^^^^^^^^ + +- Use ISO standard C++ (the 2011 version of the standard), headers + should also adhere to the 1998 version of the standard. + +- Use C++ style // one-line comments for single-line comments. + +- No compiler warnings with ``gcc -std=c++11 -Wall -Wno-write-strings``. There + should also be no errors with ``-pedantic`` added. + + +Code lay-out +^^^^^^^^^^^^ + +- Use 3-space indents, in files that already use them. In new source files, + that were created after this rule was introduced, use 4-space indents. + + At some point, the whole codebase may be converted to use only + 4-space indents. + +- No line should be longer than 79 characters. If this and the + previous rule together don't give you enough room to code, your + code is too complicated -- consider using subroutines. + +- No line should end in whitespace. If you think you need + significant trailing whitespace, think again -- somebody's + editor might delete it as a matter of routine. + +- Function definition style: function name in column 2, outermost + curly braces in column 1, blank line after local variable + declarations:: + + static int extra_ivars(PyTypeObject *type, PyTypeObject *base) + { + int t_size = PyType_BASICSIZE(type); + int b_size = PyType_BASICSIZE(base); + + assert(t_size >= b_size); /* type smaller than base! */ + ... + return 1; + } + +- Code structure: one space between keywords like 'if', 'for' and + the following left paren; no spaces inside the paren; braces as + shown:: + + if (mro != NULL) { + ... + } + else { + ... + } + +- The return statement should *not* get redundant parentheses:: + + return Py_None; /* correct */ + return(Py_None); /* incorrect */ + +- Function and macro call style: ``foo(a, b, c)`` -- no space before + the open paren, no spaces inside the parens, no spaces before + commas, one space after each comma. + +- Always put spaces around assignment, Boolean and comparison + operators. In expressions using a lot of operators, add spaces + around the outermost (lowest-priority) operators. + +- Breaking long lines: if you can, break after commas in the + outermost argument list. Always indent continuation lines + appropriately, e.g.:: + + PyErr_Format(PyExc_TypeError, + "cannot create '%.100s' instances", + type->tp_name); + +- When you break a long expression at a binary operator, the + operator goes at the end of the previous line, e.g.:: + + if (type->tp_dictoffset != 0 && base->tp_dictoffset == 0 && + type->tp_dictoffset == b_size && + (size_t)t_size == b_size + sizeof(PyObject *)) + return 0; /* "Forgive" adding a __dict__ only */ + +- Put blank lines around functions, structure definitions, and + major sections inside functions. + +- Comments go before the code they describe. + +- All functions and global variables should be declared static + unless they are to be part of a published interface + + +Naming conventions +^^^^^^^^^^^^^^^^^^ + +- Use a ``Py`` prefix for public functions; never for static + functions. The ``Py_`` prefix is reserved for global service + routines like ``Py_FatalError``; specific groups of routines + (e.g. specific object type APIs) use a longer prefix, + e.g. ``PyString_`` for string functions. + +- Public functions and variables use MixedCase with underscores, + like this: ``PyObject_GetAttr``, ``Py_BuildValue``, ``PyExc_TypeError``. + +- Internal functions and variables use lowercase with underscores, like + this: ``hashes_get_sha1.`` + +- Occasionally an "internal" function has to be visible to the + loader; we use the _Py prefix for this, e.g.: ``_PyObject_Dump``. + +- Macros should have a MixedCase prefix and then use upper case, + for example: ``PyString_AS_STRING``, ``Py_PRINT_RAW``. + + +Documentation Strings +^^^^^^^^^^^^^^^^^^^^^ +- The first line of each function docstring should be a "signature + line" that gives a brief synopsis of the arguments and return + value. For example:: + + PyDoc_STRVAR(myfunction__doc__, + "myfunction(name: str, value) -> bool\n\n" + "Determine whether name and value make a valid pair."); + + The signature line should be formatted using the format for function + annotations described in :PEP:`3107`, whereas the annotations shall reflect + the name of the type (e.g. ``str``). The leading ``def`` and the trailing + ``:`` as used for function definitions must not be included. + + Always include a blank line between the signature line and the + text of the description. + + If the return value for the function is always ``None`` (because + there is no meaningful return value), do not include the + indication of the return type. + +- When writing multi-line docstrings, be sure to always use + string literal concatenation:: + + PyDoc_STRVAR(myfunction__doc__, + "myfunction(name, value) -> bool\n\n" + "Determine whether name and value make a valid pair."); + + +Python Coding Style +------------------- +The coding style for all code written in python is :PEP:`8`. Exceptions from +this rule are the documentation, where code is sometimes formatted differently +to explain aspects. + +When writing code, use tools like pylint, pyflakes, pychecker and pycodestyle +(all available from Debian/Ubuntu) to verify that your code is +OK. Fix all the problems which seem reasonable, and mention the unfixed issues +when asking for merge. + +All code must work on both Python 2 and Python 3. + +Submitting your patch +--------------------- +First of all, the patch you create should be based against the most current +branch of python-apt (debian/sid or debian/experimental). If it is a bugfix, +you should probably use debian/sid. If you choose the wrong branch, we will +ask you to rebase your patches against the correct one. + +Once you have made your change, check that it: + + * conforms to :PEP:`8` (checked with pycodestyle). It should, at least not + introduce new errors. (and never have whitespace at end of line) + * produces no new errors in pychecker, pyflakes and pylint (unless you + can't fix them, but please tell so when requesting the merge, so it can + be fixed before hitting one of the main branches). + * does not change the behaviour of existing code in a non-compatible way. + * works on both Python 2 and Python 3. + +If your change follows all points of the checklist, you can commit it to your +repository. (You could commit it first, and check later, and then commit the +fixes, but commits should be logical and it makes no sense to have to commits +for one logical unit). + +The changelog message should follow standard git format. At the end of the +message, tags understood by gbp-dch and other tags may be added. An example +commit message could be: + +.. code-block:: none + + apt.package: Fix blah blah + + Fix a small bug where foo is doing bar, but should be doing baz + instead. + + Closes: #bugnumber + LP: #ubuntu-bug-number + Reported-By: Bug Reporter Name + + +Once you have made all your changes, you can run ``git format-patch``, +specifying the upstream commit or branch you want to create patches +against. Then you can either: + +* report a bug against the python-apt package, attach the patches + you created in the previous step, and tag it with 'patch'. It might also be + a good idea to prefix the bug report with '[PATCH]'. + +* send the patches via ``git send-email``. + +For larger patch series, you can also publish a git branch on a +public repository and request it to be pulled. + +If you choose that approach, you may want to base your patches against +the latest release, and not against some random commit, for the sake of +preserving a sane git history. + +Be prepared to rebase such a branch, and close any bugs you fix in the +branch by mentioning them in the commit message using a Closes or LP +tag. + + +Documentation updates +--------------------- +If you want to update the documentation, please follow the procedure as written +above. You can send your content in plain text, but reStructuredText is the +preferred format. I (Julian Andres Klode) will review your patch and include +it. + +.. highlight:: sh + +Example patch session +---------------------- +In the following example, we edit a file, create a patch (an enhanced +patch), and report a wishlist bug with this patch against the python-apt +package:: + + user@ pc:~$ git clone git://anonscm.debian.org/apt/python-apt.git + user@pc:~$ cd python-apt + user@pc:~/python-apt$ editor FILES + user@pc:~/python-apt$ pycodestyle FILES # Check with pycodestyle + user@pc:~/python-apt$ pylint -e FILES # Check with pylint + user@pc:~/python-apt$ pyflakes FILES # Check with pyflakes + user@pc:~/python-apt$ pychecker FILES # Check with pychecker + user@pc:~/python-apt$ git commit -p + user@pc:~/python-apt$ git format-patch origin/HEAD + user@pc:~/python-apt$ reportbug --severity=wishlist --tag=patch --attach= ... python-apt + +You may also send the patches to the mailing list instead of +reporting the bug:: + + user@pc:~/python-apt$ git send-email --to=deity@lists.debian.org + +You can even push your changes to your own repository and request +a pull request. diff --git a/doc/source/tutorials/index.rst b/doc/source/tutorials/index.rst new file mode 100644 index 0000000..06d31c6 --- /dev/null +++ b/doc/source/tutorials/index.rst @@ -0,0 +1,8 @@ +Tutorials +========= + +.. toctree:: + :maxdepth: 1 + :glob: + + * diff --git a/doc/source/whatsnew/0.7.100.rst b/doc/source/whatsnew/0.7.100.rst new file mode 100644 index 0000000..eda2764 --- /dev/null +++ b/doc/source/whatsnew/0.7.100.rst @@ -0,0 +1,211 @@ +What's New In python-apt 0.7.100 +================================ +Python-apt 0.7.100 is a new major release of the python bindings for the APT +package management libraries. It provides support for Python 3, new language +features and an API conforming to :PEP:`8`. + +Despite the many changes made in python-apt 0.7.100, the release still provides +backwards compatibility to the 0.7 series. This makes it possible to run your +old applications. + +This documents describes the important changes introduced since the release +of python-apt 0.7.10.3, starting with the first development release 0.7.90 +from April 2009. + +.. note:: + + Applications using the old API should be updated to the new API because + the old ones will be dropped in a future release. To build a python-apt + variant without the deprecated API, build it without the -DCOMPAT_0_7 + compiler flag. + +Support for Python 3 +-------------------- +Python-apt is the first Debian package to support the third major release of +Python. The port is straight forward and integrates as nicely in Python 3 as +the Python 2 builds integrate in Python 2. + +Please be aware that python-apt builds for Python 3 are built without the +compatibility options enabled for Python 2 builds. They also do not provide +methods like :meth:`has_key` on mapping objects, because it has been removed +in Python 3. + +Python 3 support may be disabled by distributions. + +Real classes in :mod:`apt_pkg` +------------------------------ +The 0.7.100 release introduces real classes in the :mod:`apt_pkg` extension. This +is an important step forward and makes writing code much easier, because you +can see the classes without having to create an object first. It also makes +it easier to talk about those classes, because they have a real name now. + +The 0.7 series shipped many functions for creating new objects, because the +classes were not exported. In 0.7.100, the classes themselves replace those +functions, as you can see in the following table. + +.. table:: + + ===================================== ================================= + Function Replacing class + ===================================== ================================= + :func:`apt_pkg.GetAcquire` :class:`apt_pkg.Acquire` + :func:`apt_pkg.GetCache()` :class:`apt_pkg.Cache` + :func:`apt_pkg.GetCdrom()` :class:`apt_pkg.Cdrom` + :func:`apt_pkg.GetDepCache()` :class:`apt_pkg.DepCache` + :func:`apt_pkg.GetPackageManager` :class:`apt_pkg.PackageManager` + :func:`apt_pkg.GetPkgAcqFile` :class:`apt_pkg.AcquireFile` + :func:`apt_pkg.GetPkgActionGroup` :class:`apt_pkg.ActionGroup` + :func:`apt_pkg.GetPkgProblemResolver` :class:`apt_pkg.ProblemResolver` + :func:`apt_pkg.GetPkgRecords` :class:`apt_pkg.PackageRecords` + :func:`apt_pkg.GetPkgSourceList` :class:`apt_pkg.SourceList` + :func:`apt_pkg.GetPkgSrcRecords` :class:`apt_pkg.SourceRecords` + :func:`apt_pkg.ParseSection` :class:`apt_pkg.TagSection` + :func:`apt_pkg.ParseTagFile` :class:`apt_pkg.TagFile` + ===================================== ================================= + +Complete rename of functions, methods and attributes +----------------------------------------------------- +In May 2008, Ben Finney reported bug 481061 against the python-apt package, +asking for PEP8 conformant names. With the release of python-apt 0.7.100, this +is finally happening. + +Context managers for the :keyword:`with` statement +-------------------------------------------------- +This is not a real big change, but it's good to have it: +:class:`apt_pkg.ActionGroup` can now be used as a context manager for the +:keyword:`with` statement. This makes it more obvious that you are using an +action group, and is just cooler:: + + with apt_pkg.ActionGroup(depcache): + for package in my_selected_packages: + depcache.mark_install(package) + +This also works for :class:`apt.Cache`:: + + with cache.actiongroup(): # cache is an Instance of apt.Cache + for package in my_selected_packages: + package.mark_install() # Instance of apt.Package + +Yet another context manager is available for locking the package system:: + + with apt_pkg.SystemLock(): + # do your stuff here + pass + +There is also one for file based locking:: + + with apt_pkg.FileLock(filename): + # do your stuff here + pass + + +Unification of dependency handling +---------------------------------- +In apt 0.7.XX, there were three different return types of functions parsing +dependencies. + +First of all, there were :func:`apt_pkg.ParseDepends()` and +:func:`apt_pkg.ParseSrcDepends()` which returned a list of or groups (which +are lists themselves) which contain tuples in the format ``(package,ver,op)``, +whereas op is one of "<=",">=","<<",">>","=","!=". + +Secondly, there was Package.DependsListStr which returned a dictionary mapping +the type of the dependency (e.g. 'Depends', 'Recommends') to a list similar to +those of :func:`apt_pkg.ParseDepends()`. The only difference was that the +values ">>", "<<" of op are ">", "<" instead. + +Thirdly, there was SourceRecords.BuildDepends, which returned a simple list +of tuples in the format ``(package, version, op, type)``, whereas ``op`` was +the integer representation of those ">>", "<<" actions and ``type`` an integer +representing the type of the dependency (e.g. 'Build-Depends'). The whole +format was almost useless from the Python perspective because the string +representations or constants for checking the values were not exported. + +python-apt 0.7.100 puts an end to this confusion and uses one basic format, which +is the format known from Package.DependsListStr. The format change only applies +to the new functions and attributes, i.e. :attr:`SourceRecords.build_depends` +will now return a dict, whereas :attr:`SourceRecords.BuildDepends` will still +return the classic format. The functions :func:`apt_pkg.parse_depends` and +:func:`apt_pkg.parse_src_depends` now use the same values for ``op`` as +:attr:`Package.DependsListStr` does. + +Example:: + + >>> s = apt_pkg.SourceRecords() + >>> s.lookup("apt") + 1 + >>> s.build_depends + {'Build-Depends': [[('debhelper', '5.0', '>=')], + [('libdb-dev', '', '')], + [('gettext', '0.12', '>=')], + [('libcurl4-gnutls-dev', '', ''), + ('libcurl3-gnutls-dev', '7.15.5', '>=')], + [('debiandoc-sgml', '', '')], + [('docbook-utils', '0.6.12', '>=')], + [('xsltproc', '', '')], + [('docbook-xsl', '', '')], + [('xmlto', '', '')]]} + >>> s.BuildDepends + [('debhelper', '5.0', 2, 0), + ('libdb-dev', '', 0, 0), + ('gettext', '0.12', 2, 0), + ('libcurl4-gnutls-dev', '', 16, 0), + ('libcurl3-gnutls-dev', '7.15.5', 2, 0), + ('debiandoc-sgml', '', 0, 0), + ('docbook-utils', '0.6.12', 2, 0), + ('xsltproc', '', 0, 0), + ('docbook-xsl', '', 0, 0), + ('xmlto', '', 0, 0)] + +C++ headers +------------ +The 0.7.100 release introduces python-apt-dev which provides headers for +developers to provide Python support in the libapt-pkg-using application. + +Redesign of :mod:`apt_inst` +--------------------------- +The 0.7.100 series redesigns the :mod:`apt_inst` module to provide +more flexible classes replacing the older functions. The older functions +are still available in Python 2 builds, but are deprecated and will be +removed in the future. + +Other changes +------------- +This release of python-apt also features several other, smaller changes: + + * Reduced memory usage by making :class:`apt.Cache` create + :class:`apt.Package()` object dynamically, instead of creating all of + them during the cache initialization. + * Support to set the candidate version in :class:`apt.package.Package` + * Support for reading gzip-compressed files in apt_pkg.TagFile. + * Various changes to :mod:`apt.debfile` have been merged from gdebi. + +There have been various other changes, see the changelog for a complete list +of changes. + + +Porting your applications to the new python-apt API +---------------------------------------------------- +Porting your application to the new python-apt API may be trivial. You +should download the source tarball of python-apt and run the tool +utils/migrate-0.8 over your code:: + + utils/migrate-0.8.py -c myapp.py mypackage/ + +This will search your code for places where possibly deprecated names are +used. Using the argument ``-c``, you can turn colorized output on. + +Now that you know which parts of your code have to be changed, you have to know +how to do this. For classes, please look at the table. For all attributes, +methods, functions, and their parameters the following rules apply: + + 1. Replace leading [A-Z] with [a-z] (e.g DescURI => descURI) + 2. Replace multiple [A-Z] with [A-Z][a-z] (e.g. descURI => descUri) + 3. Replace every [A-Z] with the corresponding [a-z] (descUri => desc_uri) + +As an exception, refixes such as 'de' (e.g. 'dequote') or 'un' (e.g. 'unlock') +are normally not separated by underscores from the next word. There are also +some other exceptions which are listed here, and apply to any name containing +this word: **filename**, **filesize**, **destdir**, **destfile**, **dequote**, +**unlock**, **reinstall**, **pinfile**, **REINSTREQ**, **UNPACKED**, +**parse_commandline**. diff --git a/doc/source/whatsnew/0.8.0.rst b/doc/source/whatsnew/0.8.0.rst new file mode 100644 index 0000000..2eeb135 --- /dev/null +++ b/doc/source/whatsnew/0.8.0.rst @@ -0,0 +1,38 @@ +What's New In python-apt 0.8 +============================ +Python-apt 0.8 is a new major release of the python bindings for the APT +package management libraries. + + +Removal of old API +------------------ +The old API that was deprecated in 0.7.100 is no longer available. Applications +that have not yet updated to the new API should do so. + +Multi-arch support +------------------ +This version of python-apt introduces multi-arch support: + + * A new class, :class:`apt_pkg.Group` has been added. + * :class:`apt_pkg.Cache` can now be indexed by ``(name, architecture)`` + tuples + +Features for mancoosi +---------------------- +Several new features related to ordering have been added on request +of the mancoosi project: + + * A new class :class:`apt_pkg.OrderList` has been added + * The :class:`apt_pkg.PackageManager` class now provides new methods + for registering install/remove/configure actions which can be + subclassed to check ordering. + +Other changes +------------- +This release of python-apt also features several other, smaller changes: + + * apt_pkg.Cache() now takes None for the progress parameter, preventing + progress reporting. + +There have been various other changes, see the changelog for a complete list +of changes. diff --git a/doc/source/whatsnew/0.9.4.rst b/doc/source/whatsnew/0.9.4.rst new file mode 100644 index 0000000..617ef08 --- /dev/null +++ b/doc/source/whatsnew/0.9.4.rst @@ -0,0 +1,17 @@ +What's New In python-apt 0.9.4 +============================== +Python-apt 0.9.4 is a maintenance update. + +New features +------------ + + * Support for apt_pkg.sha512sum() + * Support for apt_pkg.maybe_open_clear_signed_file() + * Use apt_pkg.open_maybe_clear_signed_file() when opening a .dsc file + * add MULTI_ARCH_NO constant (MULTI_ARCH_NONE is deprecated) + +Maintenance +----------- + + * Add Ubuntu Wily + * Update examples diff --git a/doc/source/whatsnew/1.0.rst b/doc/source/whatsnew/1.0.rst new file mode 100644 index 0000000..b3364ad --- /dev/null +++ b/doc/source/whatsnew/1.0.rst @@ -0,0 +1,75 @@ +What's New In python-apt 1.0 +============================== +Python-Apt 1.0 fixes several issues and use of deprecated methods. Most +importantly, it introduces large file support + +New features +------------ +* :class:`apt_pkg.AcquireFile` can now take a hash string that is not an + md5 value, using the new `hash` argument. +* A new a :meth:`apt_pkg.TagFile.close` method was added +* :class:`apt_pkg.TagFile` is now a context manager + +* The high-level cache class, :class:`apt.cache.Cache` and it's companion + :class:`apt.cache.FilteredCache` now support package + names with special architecture qualifiers such as :all and :native. + +* The method :meth:`apt.cache.Cache.connect2` allows connecting callbacks on + cache changes that take the cache as their first argument, reducing the + potential for reference cycles. + +* The property :attr:`apt.package.Version.is_installed` was added. +* The properties :attr:`apt.package.BaseDependency.installed_target_versions` + and :attr:`apt.package.Dependency.installed_target_versions` were added. + +* The property :class:`apt.Dependency.rawtype` was added to give the raw type + of a dependency, such as 'Depends'. + +* The attribute :attr:`apt_pkg.Dependency.comp_type_deb` and the property + :attr:`apt.Dependency.relation_deb` were added, they return a Debian-style + comparison operator instead of a mathematical-style one. + +* A new filter for filtered caches is provided, :class:`apt.cache.InstalledFilter`. + +Backward-incompatible changes +----------------------------- +* :class:`apt.Version` now compares package names in addition to version only + when checking for equality. This was broken previously. + +Deprecated +---------- +The following features are deprecated, starting with this release: + +* The `section` member of :class:`apt_pkg.Package` +* The `files` member of of :class:`apt_pkg.SourceRecords` +* The `md5` argument to :class:`apt_pkg.AcquireFile`, it is replaced by + the `hash` argument. +* The method :meth:`apt.cache.Cache.connect` has been deprecated. It is + replaced by :meth:`apt.cache.Cache.connect2` which is more flexible and + less prone to reference cycles. +* The attribute :attr:`apt_pkg.AcquireItem.mode` has been replaced by + :attr:`apt_pkg.AcquireItem.active_subprocess` +* The class :class:`apt_pkg.IndexRecords` has been deprecated and will + be removed in the next release. + +Removed +------- +* The module :mod:`apt.progress.gtk2` has been removed. There were no + users in the Debian archive, its last update was in 2013, and it was buggy + already. Apart from that, it suggested that it is OK to run a graphical + application as root, and used the unmaintained GTK+ 2 version. + + Therefore, there is no replacement, please use PackageKit or aptdaemon + for installation in graphical environments. +* The attribute :attr:`apt_pkg.Package.auto` was not set anymore, and thus + removed. + +Maintenance +----------- +* The classes :class:`apt.cache.Cache` and :class:`apt.cache.FilteredCache` no + longer store cyclic references to/between them. This fixes a huge issue, + because a cache can have tens of open file descriptors, causing the maximum + of file descriptors to be reached easily. + +* :mod:`apt_inst` now supports ar and tar archives that are larger than 4 GiB +* Various smaller bug fixes diff --git a/doc/source/whatsnew/1.1.rst b/doc/source/whatsnew/1.1.rst new file mode 100644 index 0000000..5a4f5c3 --- /dev/null +++ b/doc/source/whatsnew/1.1.rst @@ -0,0 +1,28 @@ +What's New In python-apt 1.1 +============================== +This release is built against APT 1.1 + +Highlights +---------- +* Code that previously raised :class:`SystemError` now raises + :class:`apt_pkg.Error`. + +Removed +------- +* The class :class:`apt_pkg.IndexRecords` has been removed, as it was removed + in APT 1.1 +* :attr:`apt_pkg.Dependency.smart_target_pkg` has been removed. + +Added +------ +* The class :class:`apt_pkg.HashStringList` has been added. +* The class :class:`apt_pkg.Error` and an alias :class:`apt_inst.Error` has + been added. + + +Deprecated +---------- +* :attr:`apt_pkg.PackageRecords.md5_hash`, + :attr:`apt_pkg.PackageRecords.sha1_hash`, and + :attr:`apt_pkg.PackageRecords.sha256_hash` + are replaced by :attr:`apt_pkg.PackageRecords.hashes`. diff --git a/doc/source/whatsnew/1.4.rst b/doc/source/whatsnew/1.4.rst new file mode 100644 index 0000000..fa3f95d --- /dev/null +++ b/doc/source/whatsnew/1.4.rst @@ -0,0 +1,16 @@ +What's New In python-apt 1.4 +============================ +This release is built against APT 1.4, see :doc:`1.1` for the other changes +since 1.0, the last series with a feature-complete release. There are no 1.2 +or 1.3 series. + +Added +------ +* The methods :meth:`apt_pkg.parse_depends` and :meth:`apt_pkg.parse_src_depends` + gained a new parameter *architecture* to change the architecture the dependency lines + are interpreted for, matching the change in apt 1.4~beta3. + + This only really makes sense for the latter option right now, as it only + affects the parsing of architecture lists. + + By default, the host architecture is used. diff --git a/doc/source/whatsnew/1.6.rst b/doc/source/whatsnew/1.6.rst new file mode 100644 index 0000000..2015bee --- /dev/null +++ b/doc/source/whatsnew/1.6.rst @@ -0,0 +1,26 @@ +What's New In python-apt 1.6 +============================ + +Changed +------- +* Methods of :class:`apt_pkg.DepCache` now raise an exception if passed + objects belonging to a different cache, in order to avoid segmentation + faults or wrong behavior. + + .. versionchanged:: 1.6.1 + + Starting with 1.6.1 and 1.7~alpha1, the exception raised is + :class:`apt_pkg.CacheMismatchError`, and :class:`apt.cache.Cache` will + automatically remap open packages and versions to a new cache. + +* Initial type hints + +* :attr:`apt_pkg.SourceRecords.files` now returns a + :class:`apt_pkg.SourceRecordsFile` object with getters instead of + a tuple (but it also emulates the tuple). + +Bugfixes +-------- +* Various other fixes for segmentation faults +* apt/auth.py: Protect against race with gpg when removing tmpdir + (Closes: #871585) diff --git a/doc/source/whatsnew/1.7.rst b/doc/source/whatsnew/1.7.rst new file mode 100644 index 0000000..38485f7 --- /dev/null +++ b/doc/source/whatsnew/1.7.rst @@ -0,0 +1,42 @@ +What's New In python-apt 1.7 +============================ + +Changed +-------- +* Starting with 1.6.1 and 1.7~alpha1, the exception raised when + passing objects of a different cache to :class:`apt_pkg.DepCache` + is :class:`apt_pkg.CacheMismatchError`, and :class:`apt.cache.Cache` will + automatically remap open packages and versions to a new cache. + +* :meth:`apt_pkg.Policy.get_priority()` now accepts :class:`apt_pkg.Version` + objects in addition to :class:`apt_pkg.Package` and :class:`apt_pkg.PackageFile` + ones. + +* :attr:`apt.package.Version.policy_priority` now returns the priority + for that version rather than the highest priority for one of its + package files. + +* :meth:`apt.Cache.commit` and :meth:`apt_pkg.DepCache.commit` now use + frontend locking to run dpkg. + +Added +------ +* The class :class:`apt_pkg.PackageRecords` can now lookup custom fields + using ``records[key]`` and ``key in records``. + + +* All code is now statically typed. Some methods from :mod:`apt_pkg` + and :mod:`apt_inst` might still be missing or more strict than + necessary. + +* A new method :meth:`apt.cache.Cache.fix_broken` has been added. + +* New methods for frontend locking have been added: + :meth:`apt_pkg.pkgsystem_lock_inner`, + :meth:`apt_pkg.pkgsystem_unlock_inner`, + :meth:`apt_pkg.pkgsystem_is_locked` (starting in alpha 3). + +Deprecated +---------- +* :meth:`apt_pkg.Policy.get_priority()` accepting :class:`apt_pkg.Package` + is deprecated. diff --git a/doc/source/whatsnew/1.8.rst b/doc/source/whatsnew/1.8.rst new file mode 100644 index 0000000..0f9704f --- /dev/null +++ b/doc/source/whatsnew/1.8.rst @@ -0,0 +1,8 @@ +What's New In python-apt 1.8 +============================ + + +Added +------ +* A new method :meth:`apt_pkg.Policy.init_defaults` has been added + in 1.8.2. diff --git a/doc/source/whatsnew/2.0.rst b/doc/source/whatsnew/2.0.rst new file mode 100644 index 0000000..ed2b063 --- /dev/null +++ b/doc/source/whatsnew/2.0.rst @@ -0,0 +1,37 @@ +What's New In python-apt 2.0 +============================ +Changes since 1.8. + +Added +----- +* The method :meth:`apt_pkg.TagSection.write()` has been added +* The attribute :attr:`apt_pkg.HashString.hashvalue` has been added +* The constructor :class:`apt_pkg.AcquireFile` now accepts an + :class:`apt_pkg.HashStringList` as the *hash* argument. + +* The classes :class:`apt_pkg.HashString` and :class:`apt_pkg.HashStringList` + gained a new ``usable`` property. + +Removed +------- +* The methods called `install_protect` have been removed +* The `section` attribute has been removed from :class:`apt_pkg.Package` + and :class:`apt.package.Package` +* The method :meth:`apt_pkg.rewrite_section` has been removed +* The attributes :attr:`apt_pkg.Hashes.md5`, :attr:`apt_pkg.Hashes.sha1`, :attr:`apt_pkg.Hashes.sha256` have been removed +* The method :meth:`apt_pkg.Policy.get_match` has been removed. +* The constructor :class:`apt_pkg.AcquireFile` no longer takes an *md5* argument. + +Changed +------- +* In :class:`apt_pkg.SourceRecords`, the tuple view of files now always contains + None where it previously contained the md5 hash. +* The method :meth:`apt_pkg.Policy.get_priority()` no longer accepts :class:`apt_pkg.Package` instances. +* Instances of :class:`apt_pkg.HashString` can now be compared for equality +* :class:`apt.progress.base.InstallProgress` is now a context manager, use it in + a ``with`` statement to avoid leaking file descriptors. + +Bug fixes +--------- + +* Fixed unterminated ``char*`` array in :class:`apt_pkg.TagRemove` constructor. diff --git a/doc/source/whatsnew/2.1.rst b/doc/source/whatsnew/2.1.rst new file mode 100644 index 0000000..ecbd995 --- /dev/null +++ b/doc/source/whatsnew/2.1.rst @@ -0,0 +1,7 @@ +What's New In python-apt 2.1 +============================ +2.1 is the development series for 2.2 + +Removed +------- +* Support for Python 2 (2.1.0) diff --git a/doc/source/whatsnew/index.rst b/doc/source/whatsnew/index.rst new file mode 100644 index 0000000..cc270a1 --- /dev/null +++ b/doc/source/whatsnew/index.rst @@ -0,0 +1,9 @@ +What's new in python-apt +======================== + +.. toctree:: + :maxdepth: 2 + :glob: + + * + diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000..c9e9b53 --- /dev/null +++ b/mypy.ini @@ -0,0 +1,2 @@ +[mypy] +mypy_path = $MYPY_CONFIG_FILE_DIR/typehinting diff --git a/po/POTFILES.in b/po/POTFILES.in new file mode 100644 index 0000000..eb91d52 --- /dev/null +++ b/po/POTFILES.in @@ -0,0 +1,8 @@ +[encoding: UTF-8] +[type: gettext/rfc822deb] data/templates/Ubuntu.info.in +[type: gettext/rfc822deb] data/templates/Debian.info.in +aptsources/distro.py +apt/package.py +apt/debfile.py +apt/progress/text.py +apt/cache.py diff --git a/po/ar.po b/po/ar.po new file mode 100644 index 0000000..73c7654 --- /dev/null +++ b/po/ar.po @@ -0,0 +1,622 @@ +# Arabic translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:14+0000\n" +"Last-Translator: Saleh Odeh \n" +"Language-Team: Arabic \n" +"Language: ar\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n == 1 ? 0 : n == 2 ? 1 : 2\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "ملاحظات الإصدار" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "تحديثات الإنترنت" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "مدعوم بشكل رسمي" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "حقوق نقل محدودة" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "تحديثات الإنترنت" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "التّفاصيل" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "الرجاء التأكد من إتصالك بالإنترنت" + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "تعذّر تثبيت '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "سيكون من الضروري إزالة رزم مهمة" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/be.po b/po/be.po new file mode 100644 index 0000000..53470c3 --- /dev/null +++ b/po/be.po @@ -0,0 +1,638 @@ +# Belarusian translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2012-06-20 18:42+0300\n" +"Last-Translator: Viktar Siarheichyk \n" +"Language-Team: Belarusian \n" +"Language: be\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2)\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD-ROM з Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD-ROM з Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD-ROM з Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD-ROM з Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Партнёры Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Праграмы, якія Canonical запакаваў для сваіх партнёраў" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Гэтая праграма не ўваходзіць у Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Незалежны" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Пададзены пабочнымі распрацоўнікамі праграмаў" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Праграма, прапанаваная пабочнымі распрацоўнікамі." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD-ROM з Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD-ROM з Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD-ROM з Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD-ROM з Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD-ROM з Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD-ROM з Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD-ROM з Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Утрымоўваецца супольнасцю" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Абмежаваная праграма" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD-ROM з Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "" +"Свабодныя праграмы і праграмы з адкрытым кодам, што падтрымваюцца Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Падтрыманыя супольнасцю (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "" +"Свабодныя праграмы і праграмы з адкрытым кодам, што падтрымваюцца супольнасцю" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Несвабодныя драйверы" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Уласніцкія драйверы прыладаў" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Абмежаваныя праграмы (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Праграмы, абмежаваныя аўтарскім правам ці юрыдычнымі пытаннямі" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CD-ROM з Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Важныя абнаўленні бяспекі" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Рэкамендаваныя абнаўленні" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Загадзя выдадзеныя абнаўленні" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Абнаўленні, што не падтрымваюцца" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD-ROM з Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Абнаўленні бяспекі Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Абнаўленні Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD-ROM з Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Афіцыйна падтрымваюцца" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Абнаўленні бяспекі Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Абнаўленні Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Падтымваецца супольнасцю (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Несвабодныя (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD-ROM з Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Больш не падтрымваюцца афіцыйна" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Абмежаванае аўтарскае права" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Абнаўленні бяспекі Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Абнаўленні Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 Backports" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 'Wheezy' " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 'Squeeze' " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 'Lenny' " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 'Etch'" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 'Sarge'" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Прапанаваныя абнаўленні" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Абнаўленні бяспекі" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Цяперашняе стабільнае выданне Debian" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian testing" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian 'Sid' (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Праграмы, сумяшчальныя з DFSG з несвабоднымі залежнымі" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Праграмы, несумяшчальныя з DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Сервер для %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Галоўны сервер" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Іншыя серверы" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Выгрузка файла %(current)li з %(total)li на хуткасці %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Загрузка файла %(current)li of %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Падрабязнасці" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Пачынаецца..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Скончана" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "Несапраўдны unicode у апісанні да '%s' (%s). Паведаміце, калі ласка." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Недасяжны спіс зменаў" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"Ліст зменаў пакуль што недасяжны.\n" +"\n" +"Глядзіце, калі ласка, http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"пакуль змены не стануць дасяжныя, альбо паспрабуйце пазней." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Не ўдалося атрымаць спіс зменаў. \n" +"Калі ласка, праверце вашае далучэнне да інтэрнэту." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Спіс файлаў да '%s' не атрымалася прачытаць" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Спіс файлаў кіравання да '%s' не атрымалася прачытаць" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Залежнасць, якую не ўдаецца задаволіць: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Канфліктуе з усталяваным пакетам '%s'" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Парушае залежнасць %(depname)s (%(deprelation)s %(depversion)s) наяўнага " +"пакета '%(pkgname)s'" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Парушае канфлікт %(targetpkg)s (%(comptype)s %(targetver)s) наяўнага пакета " +"'%(pkgname)s'" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Парушае наяўны пакет '%(pkgname)s', які канфліктуе з: '%(targetpkg)s'. Але " +"'%(debfile)s' забяспечваецца праз: '%(provides)s'" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Гэты пакет не мае поля Architecture" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Памылковая архітэктура '%s'" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Ужо ўсталяваная апошняя версія" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Не атрымалася задаволіць усе залежнасці (зламаны кэш)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "Немагчыма ўсталяваць '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Аўтаматычна распакаваны:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Аўтаматычна ператвораны ў друкаваныя ASCII:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"Усталяваць Build-Dependencies для зыходнага пакета '%s', які збірае %s\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Трэба было б выдаліць абавязковы пакет" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Скончана" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Hit " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Ign " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Err " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Атрымаць:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [Апрацоўваецца]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Змена носьбіта: Калі ласка, устаўце дыск з паметкай\n" +" '%s'\n" +"у прыладу '%s' і націсніце Enter\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Атрымана %sB з %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" +"Калі ласка, падайце імя для гэтага дыска, напрыклад, 'Debian 2.1r1 Disk 1'" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Калі ласка, устаўце дыск у прыладу і націсніце Enter" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Будуюцца структуры звестак" diff --git a/po/bg.po b/po/bg.po new file mode 100644 index 0000000..2c9942d --- /dev/null +++ b/po/bg.po @@ -0,0 +1,680 @@ +# Bulgarian translation of update manager. +# Copyright (C) 2005 THE update manager'S COPYRIGHT HOLDER +# This file is distributed under the same license as the update manager package. +# Rostislav "zbrox" Raykov , 2005. +# +# +msgid "" +msgstr "" +"Project-Id-Version: update manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:01+0000\n" +"Last-Translator: Nikola Kasabov \n" +"Language-Team: Bulgarian \n" +"Language: bg\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.10 актуализации на сигурността" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD с Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD с Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD с Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD с Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "CD с Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD с Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.10 актуализации на сигурността" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.10 актуализации на сигурността" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +#, fuzzy +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 5.10 актуализации" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Поддържани от обществото (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +#, fuzzy +msgid "Restricted software" +msgstr "Допринесен софтуер" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +#, fuzzy +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +#, fuzzy +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Поддържани от обществото (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Поддържани от обществото (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Поддържани от обществото (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +#, fuzzy +msgid "Non-free drivers" +msgstr "Несвободни (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +#, fuzzy +msgid "Restricted software (Multiverse)" +msgstr "Несвободни (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +#, fuzzy +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +#, fuzzy +msgid "Important security updates" +msgstr "Ubuntu 5.10 актуализации на сигурността" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "_Инсталиране на актуализациите" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "_Инсталиране на актуализациите" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +#, fuzzy +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 актуализации на сигурността" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 актуализации" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Състарени версии" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +#, fuzzy +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD с Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +#, fuzzy +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD с Ubuntu 5.04 „Hoary Hedgehog“" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Официално поддържани" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +#, fuzzy +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.10 актуализации на сигурността" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +#, fuzzy +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.10 актуализации" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +#, fuzzy +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.10 Състарени версии" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +#, fuzzy +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Поддържани от обществото (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Несвободни (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +#, fuzzy +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD с Ubuntu 4.10 „Warty Warthog“" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +#, fuzzy +msgid "No longer officially supported" +msgstr "Официално поддържан" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Ограничени авторски права" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 обновления по сигурността" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 обновления" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +#, fuzzy +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 5.10 Състарени версии" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 „Sarge“" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 „Sarge“" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian Testing" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian Testing" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 „Sarge“" + +#. Description +#: ../data/templates/Debian.info.in:119 +#, fuzzy +msgid "Proposed updates" +msgstr "_Инсталиране на актуализациите" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Ubuntu 5.10 актуализации на сигурността" + +#. Description +#: ../data/templates/Debian.info.in:133 +#, fuzzy +msgid "Debian current stable release" +msgstr "Debian Unstable „Sid“" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (тестване)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (нестабилен)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-съвместим софтуер с несвободни зависимости" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Софтуер несъвместим с DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Сваляне на файл %li от %li при %s/сек" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Сваляне на файл %li от %li при %s/сек" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Детайли" + +#: ../apt/progress/gtk2.py:428 +#, fuzzy +msgid "Starting..." +msgstr "Настройки" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +#, fuzzy +msgid "The list of changes is not available" +msgstr "Списъкът с промените още не е наличен. Моля, опитайте по-късно!" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Неуспех при изтегляне на списъка с промени. Моля, проверете Интернет " +"връзката си." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Не може да се инсталира '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Ще трябва да бъде премахнат важен пакет" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/bn.po b/po/bn.po new file mode 100644 index 0000000..a20804c --- /dev/null +++ b/po/bn.po @@ -0,0 +1,671 @@ +# Bengali translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:02+0000\n" +"Last-Translator: Khandakar Mujahidul Islam \n" +"Language-Team: Bengali \n" +"Language: bn\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "উবুন্টু ৫.১০ নিরাপত্তামুলক আপডেট" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "উবুন্টু ৫.১০ নিরাপত্তামুলক আপডেট" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "উবুন্টু ৫.১০ নিরাপত্তামুলক আপডেট" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +#, fuzzy +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "উবুন্টু ৫.১০ আপডেট" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +#, fuzzy +msgid "Restricted software" +msgstr "ফ্রি নয় (মাল্টিভার্স)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +#, fuzzy +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "উবুন্টু ৬.০৬ 'ড্যাপার ড্রেক'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +#, fuzzy +msgid "Non-free drivers" +msgstr "ফ্রি নয় (মাল্টিভার্স)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +#, fuzzy +msgid "Restricted software (Multiverse)" +msgstr "ফ্রি নয় (মাল্টিভার্স)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +#, fuzzy +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "উবুন্টু ৬.০৬ 'ড্যাপার ড্রেক'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +#, fuzzy +msgid "Important security updates" +msgstr "উবুন্টু ৫.১০ নিরাপত্তামুলক আপডেট" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "আপডেট ইন্সটল করো (_I)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "আপডেট ইন্সটল করো (_I)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +#, fuzzy +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "উবুন্টু ৫.১০ নিরাপত্তামুলক আপডেট" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "উবুন্টু ৫.১০ আপডেট" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "উবুন্টু ৫.১০ ব্যাকপোর্ট" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +#, fuzzy +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "অফিসিয়াল ভাবে সমর্থিত" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +#, fuzzy +msgid "Ubuntu 5.04 Security Updates" +msgstr "উবুন্টু ৫.১০ নিরাপত্তামুলক আপডেট" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +#, fuzzy +msgid "Ubuntu 5.04 Updates" +msgstr "উবুন্টু ৫.১০ আপডেট" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +#, fuzzy +msgid "Ubuntu 5.04 Backports" +msgstr "উবুন্টু ৫.১০ ব্যাকপোর্ট" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +#, fuzzy +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "উবুন্টু ৫.১০ 'ব্রিজী ব্যাজার'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "ফ্রি নয় (মাল্টিভার্স)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +#, fuzzy +msgid "No longer officially supported" +msgstr "কিছু সফটওয়্যার অফিসিয়ালি আর সমর্থিত নয়" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +#, fuzzy +msgid "Ubuntu 4.10 Security Updates" +msgstr "উবুন্টু ৫.১০ নিরাপত্তামুলক আপডেট" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +#, fuzzy +msgid "Ubuntu 4.10 Updates" +msgstr "উবুন্টু ৫.১০ আপডেট" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +#, fuzzy +msgid "Ubuntu 4.10 Backports" +msgstr "উবুন্টু ৫.১০ ব্যাকপোর্ট" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "ডেবিয়ান ৩.১ \"সার্জ\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "ডেবিয়ান ৩.১ \"সার্জ\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "ডেবিয়ান ৩.১ \"সার্জ\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "ডেবিয়ান ৩.১ \"সার্জ\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "ডেবিয়ান ৩.১ \"সার্জ\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +#, fuzzy +msgid "Proposed updates" +msgstr "আপডেট ইন্সটল করো (_I)" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "উবুন্টু ৫.১০ নিরাপত্তামুলক আপডেট" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "ডেবিয়ান \"Etch\" (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "ডেবিয়ান \"Sid\" (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "বিস্তারিত" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +#, fuzzy +msgid "The list of changes is not available" +msgstr "পরিবর্তনের তালিকা এখনে উপস্হিত নয়। অনুগ্রহ করে পরে আবার চেষ্টা করুন।" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"পরিবর্তন তালিকা ডাউনলোড করতে ব্যর্থ। অনুগ্রহ করে আপনার ইন্টারনেট সংযোগ পরীক্ষা করুন।" + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "'%s' ইন্সটল করা যাচ্ছে না" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "একটি প্রয়োজনীয় প্যকেজ অপসারণ করা হতে পারে" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/ca.po b/po/ca.po new file mode 100644 index 0000000..524a4ce --- /dev/null +++ b/po/ca.po @@ -0,0 +1,679 @@ +# Catalan translation for update-manager +# Copyright (C) 2006 +# This file is distributed under the same license as the update-manager package. +# Jordi Irazuzta Cardús , 2006. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:14+0000\n" +"Last-Translator: Jordi Irazuzta \n" +"Language-Team: Catalan \n" +"Language: ca\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Actualitzacions de seguretat d'Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD amb Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD amb Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD amb Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD amb Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD amb Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "CD amb Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD amb Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Actualitzacions de seguretat d'Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD amb Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Actualitzacions de seguretat d'Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD amb Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +#, fuzzy +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Actualitzacions d'Ubuntu 5.10" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Paquets mantinguts per la comunitat (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +#, fuzzy +msgid "Restricted software" +msgstr "Programari de la comunitat" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +#, fuzzy +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +#, fuzzy +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Paquets mantinguts per la comunitat (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Paquets mantinguts per la comunitat (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Paquets mantinguts per la comunitat (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +#, fuzzy +msgid "Non-free drivers" +msgstr "Paquets sense llicència lliure (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +#, fuzzy +msgid "Restricted software (Multiverse)" +msgstr "Paquets sense llicència lliure (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +#, fuzzy +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +#, fuzzy +msgid "Important security updates" +msgstr "Debian Stable Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "_Instal·la les actualitzacions" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "_Instal·la les actualitzacions" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +#, fuzzy +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD amb Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Actualitzacions de seguretat d'Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Actualitzacions d'Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +#, fuzzy +msgid "Ubuntu 5.10 Backports" +msgstr "Actualitzacions d'Ubuntu 6.06 LTS" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +#, fuzzy +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD amb Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +#, fuzzy +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD amb Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Paquets mantinguts oficialment (Main)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Actualitzacions de seguretat d'Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Actualitzacions d'Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +#, fuzzy +msgid "Ubuntu 5.04 Backports" +msgstr "Actualitzacions d'Ubuntu 6.06 LTS" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +#, fuzzy +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Paquets mantinguts per la comunitat (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Paquets sense llicència lliure (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +#, fuzzy +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD amb Ubuntu 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +#, fuzzy +msgid "No longer officially supported" +msgstr "Algun programari ja no es mantindrà oficialment" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Paquets amb restriccions per copyright (Restricted)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Actualitzacions de seguretat d'Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Actualitzacions d'Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +#, fuzzy +msgid "Ubuntu 4.10 Backports" +msgstr "Actualitzacions d'Ubuntu 6.06 LTS" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +#, fuzzy +msgid "Proposed updates" +msgstr "_Instal·la les actualitzacions" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Debian Stable Security Updates" + +#. Description +#: ../data/templates/Debian.info.in:133 +#, fuzzy +msgid "Debian current stable release" +msgstr "Debian Unstable \"Sid\"" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian Testing" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Programari compatible DFSG amb dependències no lliures" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Programari no compatible DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Servidor principal" + +#: ../aptsources/distro.py:250 +#, fuzzy +msgid "Custom servers" +msgstr "Servidor més proper" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "S'està descarregant el fitxer %li de %li amb %s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "S'està descarregant el fitxer %li de %li amb %s/s" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detalls" + +#: ../apt/progress/gtk2.py:428 +#, fuzzy +msgid "Starting..." +msgstr "Paràmetres" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +#, fuzzy +msgid "The list of changes is not available" +msgstr "La llista de canvis encara no està disponible. Proveu-ho després." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"S'ha produït un error en descarregar els canvis. Comproveu si teniu connexió " +"a Internet." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "No s'ha pogut instal·lar '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "S'haurà d'esborrar un paquet essencial" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/cs.po b/po/cs.po new file mode 100644 index 0000000..5e9fd73 --- /dev/null +++ b/po/cs.po @@ -0,0 +1,660 @@ +# Czech translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-18 22:54+0000\n" +"Last-Translator: Dominik Sauer \n" +"Language-Team: Czech \n" +"Language: cs\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Bezpečnostní aktualizace Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Cdrom s Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Cdrom s Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Cdrom s Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Cdrom s Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Cdrom s Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Cdrom s Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Cdrom s Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Cdrom s Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Cdrom s Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Bezpečnostní aktualizace Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Cdrom s Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Bezpečnostní aktualizace Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Cdrom s Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Udržováno komunitou" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Nesvobodný software" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Cdrom s Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Svobodný software oficiálně podporovaný společností Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Udržováno komunitou (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Software s otevřeným zdrojovým kódem, který je udržován komunitou" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Nesvobodné ovladače" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Patentované (proprietární) ovladače zařízení" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Software s omezující licencí (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Software omezený ochrannou známkou nebo jinými právními prostředky" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Cdrom s Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Důležité bezpečnostní aktualizace" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Doporučené aktualizace" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Navržené aktualizace" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Aktualizace přenesené z vyšších verzí distribuce" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Cdrom s Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Bezpečnostní aktualizace Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Aktualizace Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Software přenesený z vyšší verze distribuce na Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Cdrom s Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Oficiálně podporováno" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Bezpečnostní aktualizace Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Aktualizace Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Aplikace přenesené z vyšších verzí distribuce na Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Udržováno komunitou (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Nesvobodný (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Cdrom s Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Již není oficiálně podporováno" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Omezený copyright" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Bezpečnostní aktualizace Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Aktualizace Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Aplikace přenesené z vyšších verzí distribuce na Ubuntu 4.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Navržené aktualizace" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Důležité bezpečnostní aktualizace" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Software kompatibilní s DFSG, ale závisející na nesvobodných balících" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Software nekompatibilní s DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Server pro zemi \"%s\"" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Hlavní server" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Uživatelem vybrané servery" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Stahuji %(current)li. soubor z %(total)li rychlostí %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Stahuji %(current)li. soubor of %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Podrobnosti" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Seznam změn není dostupný." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Stažení seznamu změn selhalo. \n" +"Prosím zkontrolujte své internetové připojení." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Nemohu nainstalovat '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Toto by vedlo k odstranění základního balíku" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/csb.po b/po/csb.po new file mode 100644 index 0000000..7335992 --- /dev/null +++ b/po/csb.po @@ -0,0 +1,621 @@ +# Kashubian translation for update-manager +# Copyright (c) 2006 Rosetta Contributors and Canonical Ltd 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-08 04:10+0000\n" +"Last-Translator: Michôł Òstrowsczi \n" +"Language-Team: Kashubian \n" +"Language: csb\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "%s aktualizacëji" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "%s aktualizacëji" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Serwera dlô kraju %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Przédny serwera" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Jine serwerë" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +#, fuzzy +msgid "Details" +msgstr "Codniowò" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Nie je mòżno zainstalowac '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/da.po b/po/da.po new file mode 100644 index 0000000..9deb967 --- /dev/null +++ b/po/da.po @@ -0,0 +1,637 @@ +# Danish translation python-apt. +# Copyright (C) 2012 python-apt & nedenstående oversætttere. +# This file is distributed under the same license as the python-apt package. +# Mads Bille Lundby , 2009. +# AJenbo , 2011. +# Ask, 2011. +# Joe Hansen , 2011, 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: python-apt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2012-10-06 14:44+0200\n" +"Last-Translator: Joe Hansen \n" +"Language-Team: Danish \n" +"Language: da\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 \"Precise Pangolin\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Cd-rom med Ubuntu 12.04 \"Precise Pangolin\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 \"Oneiric Ocelot\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Cd-rom med Ubuntu 11.10 \"Oneiric Ocelot\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 \"Natty Narwhal\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Cd-rom med Ubuntu 11.04 \"Natty Narwhal\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 \"Maverick Meerkat\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Cd-rom med Ubuntu 10.10 \"Maverick Meerkat\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Canonicalpartnere" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Programmer pakket af Canonical for deres partnere" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Dette program er ikke en del af Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Uafhængigt" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Tilbudt af tredjepartsprogramudviklere" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Programmer tilbudt af tredjepartsudviklere." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 \"Lucid Lynx\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Cd-rom med Ubuntu 10.04 \"Lucid Lynx\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 \"Karmic Koala\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Cd-rom med Ubuntu 9.10 \"Karmic Koala\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 \"Jaunty Jackalope\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Cd-rom med Ubuntu 9.04 \"Jaunty Jackalope\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 \"Intrepid Ibex\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Cd-rom med Ubuntu 8.10 \"Intrepid Ibex\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 \"Hardy Heron\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Cd-rom med Ubuntu 8.04 \"Hardy Heron\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 \"Gutsy Gibbon\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Cd-rom med Ubuntu 7.10 \"Gutsy Gibbon\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 \"Feisty Fawn\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Cd-rom med Ubuntu 7.04 \"Feisty Fawn\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 \"Edgy Eft\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Vedligeholdt af fællesskabet" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Ikke-frit software" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Cd-rom med Ubuntu 6.10 \"Edgy Eft\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS \"Dapper Drake\"" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Canonical-understøttede frie programmer med åben kildekode" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Vedligeholdt af fællesskabet (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Fællesskabsvedligeholdt frie programmer med åben kildekode" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Proprietære drivere" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Proprietære drivere til enheder" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Ikke-frit software (multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Software begrænset af ophavsret eller legale problemer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Cd-rom med Ubuntu 6.06 LTS \"Dapper Drake\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Vigtige sikkerhedsopdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Anbefalede opdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Ikke-frigivne opdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Ikke-understøttede opdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Cd-rom med Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 sikkerhedsopdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 opdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 tilbageporteringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Cd-rom med Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Understøttet officielt" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 sikkerhedsopdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 opdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 tilbageporteringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Vedligeholdt af fællesskabet (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Ikke-frit (multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Cd-rom med Ubuntu 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Ikke længere officielt supporteret" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Begrænset ophavsret" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 sikkerhedsopdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 opdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 tilbageporteringer" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 \"Wheezy\" " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 \"Squeeze\" " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 \"Lenny\" " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 \"Etch\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Foreslåede opdateringer" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Sikkerhedsopdateringer" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Debian aktuel stabil udgivelse" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian tester" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (ustabil)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-kompatibel software med ikke-frie afhængigheder" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Ikke-DFSG-kompatibel software" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Server for %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Hovedserver" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Brugerdefinerede servere" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Henter fil %(current)li af %(total)li med %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Henter fil %(current)li af %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detaljer" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Starter..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Færdig" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "Ugyldig unicode i beskrivelsen af \"%s\" (%s). Se venligst rapport." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Listen med ændringer er ikke tilgængelig" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"Listen over ændringer er ikke tilgængelig endnu\n" +"\n" +"Se venligst http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"indtil ændringerne bliver tilgængelige eller prøv igen senere." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Fejl ved hentning af ændringslisten.\n" +"Undersøg venligst din internetforbindelse." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Listen over filer for \"%s\" kunne ikke læses" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Listen over filer for \"%s\" kunne ikke læses" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Afhængighed kan ikke opfyldes; %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "I konflikt med den installerede pakke \"%s\"" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Ødelægger eksisterende pakke \"%(pkgname)s\" afhængighed %(depname)s " +"(%(deprelation)s %(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Ødelægger eksisterende pakke \"%(pkgname)s\" konflikt %(targetpkg)s (%(comptype)s " +"%(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Ødelægger eksisterende pakke \"%(pkgname)s\" som er i konflikt: \"%(targetpkg)s\". " +"Men \"%(debfile)s\" tilbyder den via: \"%(provides)s\"" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Intet arkitekturfelt i pakken" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Forkert arkitektur \"%s\"" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Der er allerede installeret en senere version" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Kunne ikke opfylde alle afhængigheder (beskadiget cache)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "Kan ikke installere \"%s\"" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Automatisk pakket ud:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Automatisk konverteret til udskrivbar ascii:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "Installer byggeafhængigheder for kildepakken \"%s\" der bygger %s\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "En nødvendig pakke vil blive fjernet" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s ... Færdig" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Tjekkede " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Ign " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Fejl " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Henter:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [Arbejder]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Medieskift: Indsæt disken med navnet\n" +" '%s'\n" +"i drevet '%s' og tryk retur\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Hentede %sB på %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "Angiv et navn for denne disk, som f.eks. 'Debian 2.1r1 Disk 1'" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Indsæt en disk i drevet og tryk retur" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Opbygger datastrukturer" + + diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..c7ee73e --- /dev/null +++ b/po/de.po @@ -0,0 +1,645 @@ +# German translation of python-apt. +# Copyright (C) 2005 Michiel Sikkes +# Copyright (C) 2009 - 2010 Julian Andres Klode +# This file is distributed under the same license as the update-manager package. +# Initial version by an unknown artist. +# Frank Arnold , 2005. +# Holger Wansing , 2012. +# +# +msgid "" +msgstr "" +"Project-Id-Version: python-apt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2012-06-17 20:23+0200\n" +"Last-Translator: Holger Wansing \n" +"Language-Team: German \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 »Precise Pangolin«" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD-ROM mit Ubuntu 12.04 »Precise Pangolin«" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 »Oneiric Ocelot«" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD-ROM mit Ubuntu 11.10 »Oneiric Ocelot«" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 »Natty Narwhal«" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD-ROM mit Ubuntu 11.04 »Natty Narwhal«" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 »Maverick Meerkat«" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD-ROM mit Ubuntu 10.10 »Maverick Meerkat«" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Canonical-Partner" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Software, die von Canonical für seine Partner paketiert wurde" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Diese Software ist nicht Teil von Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Unabhängig" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Bereitgestellt von Fremd-Software-Entwicklern" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Software, die von Fremd-Software-Entwicklern angeboten wurde" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 »Lucid Lynx«" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD-ROM mit Ubuntu 10.04 »Lucid Lynx«" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 »Karmic Koala«" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD-ROM mit Ubuntu 9.10 »Karmic Koala«" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 »Jaunty Jackalope«" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD-ROM mit Ubuntu 9.04 »Jaunty Jackalope«" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 »Intrepid Ibex«" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD-ROM mit Ubuntu 8.10 »Intrepid Ibex«" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 »Hardy Heron«" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD-ROM mit Ubuntu 8.04 »Hardy Heron«" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 »Gutsy Gibbon«" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD-ROM mit Ubuntu 7.10 »Gutsy Gibbon«" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 »Feisty Fawn«" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD-ROM mit Ubuntu 7.04 »Feisty Fawn«" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 »Edgy Eft«" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Von der Ubuntu-Gemeinde betreut" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Eingeschränkte Software" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD-ROM mit Ubuntu 6.10 »Edgy Eft«" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS »Dapper Drake«" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Von Canonical unterstützte freie und quelloffene Software" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Von der Gemeinde betreut (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Von der Ubuntu-Gemeinde betreute freie und quelloffene Software" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Proprietäre Treiber" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Proprietäre Gerätetreiber" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Eingeschränkte Software (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Rechtlich eingeschränkte Software" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CD-ROM mit Ubuntu 6.06 LTS »Dapper Drake«" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Wichtige Sicherheitsaktualisierungen" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Empfohlene Aktualisierungen" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Vorabveröffentlichte Aktualisierungen" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Nicht unterstützte Aktualisierungen" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 »Breezy Badger«" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD-ROM mit Ubuntu 5.10 »Breezy Badger«" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 Sicherheitsaktualisierungen" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 Aktualisierungen" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 »Hoary Hedgehog«" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD-ROM mit Ubuntu 5.04 »Hoary Hedgehog«" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Offiziell unterstützt" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 Sicherheitsaktualisierungen" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 Aktualisierungen" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 »Warty Warthog«" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Von der Ubuntu-Gemeinde betreut (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Unfrei (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD-ROM mit Ubuntu 4.10 »Warty Warthog«" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Unterstützung ist ausgelaufen" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Eingeschränktes Copyright" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 Sicherheitsaktualisierungen" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 Aktualisierungen" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 Backports" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 »Wheezy«" + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 »Squeeze«" + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 »Lenny«" + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 »Etch«" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 »Sarge«" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Vorgeschlagene Aktualisierungen" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Sicherheitsaktualisierungen" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Aktuelle stabile Veröffentlichung von Debian" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian Testing" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian »Sid« (Unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-kompatible Software mit unfreien Abhängigkeiten" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Nicht DFSG-kompatible Software" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Server für %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Haupt-Server" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Benutzerdefinierte Server" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" +"Datei %(current)li von %(total)li wird mit %(speed)s/s heruntergeladen." + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Datei %(current)li von %(total)li wird heruntergeladen." + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Details" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Starten ..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Fertig" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "Ungültiger Unicode-Wert in Beschreibung für '%s' (%s). Bitte melden." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Die Liste mit Änderungen ist momentan nicht verfügbar." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"Die Liste mit Änderungen ist momentan nicht verfügbar.\n" +"\n" +"Bitte benutzen Sie http://launchpad.net/ubuntu/+source/%s/%s/+changelog,\n" +"bis die Liste verfügbar ist oder versuchen sie es später erneut." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Die Liste mit Änderungen konnte nicht heruntergeladen werden. \n" +"Bitte überprüfen Sie Ihre Internet-Verbindung." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Die Liste der Dateien von »%s« konnte nicht gelesen werden." + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Die Liste der Dateien von »%s« konnte nicht gelesen werden." + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Abhängigkeit nicht erfüllbar: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Steht in Konflikt zu dem installierten Paket »%s«" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Beschädigt vorhandenes Paket »%(pkgname)s« wegen Abhängigkeit %(depname)s " +"(%(deprelation)s %(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Beschädigt vorhandenes Paket »%(pkgname)s« wegen Konflikt: %(targetpkg)s " +"(%(comptype)s %(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Beschädigt vorhandenes Paket »%(pkgname)s«, welches in Konflikt steht: " +"»%(targetpkg)s«. Aber »%(debfile)s« bietet es an über: »%(provides)s«" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Kein Architecture-Feld in dem Paket" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Falsche Architektur »%s«" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Eine neuere Version ist bereits installiert." + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" +"Es konnten nicht alle Abhängigkeiten erfüllt werden (Zwischenspeicher " +"defekt)." + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "»%s« kann nicht installiert werden." + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Automatisch entpackt:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Automatisch konvertiert in druckfähiges ASCII:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"Installieren der Bau-Abhängigkeiten für das Quellpaket »%s«, welches »%s« " +"baut\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Ein grundlegendes Paket müsste entfernt werden" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Fertig" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "OK " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Ign " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Fehl " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Hole:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [Verarbeiten]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Medienwechsel: Bitte legen Sie das Medium mit dem Namen\n" +" »%s«\n" +"in Laufwerk »%s« ein und drücken Sie die Eingabetaste.\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Es wurden %sB in %s geholt (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" +"Bitte geben Sie einen Namen für die CD an, wie zum Beispiel »Debian 2.1r1 " +"Disk 1«." + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" +"Bitte legen Sie ein Medium ins Laufwerk und drücken Sie die Eingabetaste." + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Datenstrukturen werden aufgebaut" diff --git a/po/el.po b/po/el.po new file mode 100644 index 0000000..a4a48cf --- /dev/null +++ b/po/el.po @@ -0,0 +1,638 @@ +# translation of el.po to Greek +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) 2005 THE PACKAGE'S COPYRIGHT HOLDER. +# +# Kostas Papadimas , 2005, 2006. +# Thomas Vasileiou , 2012. +msgid "" +msgstr "" +"Project-Id-Version: el\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2012-06-13 11:37+0100\n" +"Last-Translator: Thomas Vasileiou \n" +"Language-Team: Greek \n" +"Language: el\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Cdrom με Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 'Oneiric Ocelot''" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Cdrom με το Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Cdrom με το Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Cdrom με το Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Συνεργάτες της Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Πακέτο λογισμικού της Canonical για τους συνεργάτες της " + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Αυτό το λογισμικό δεν αποτελεί μέρος των Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Ανεξάρτητο" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Παρέχεται από τρίτους" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Λογισμικό που προσφέρεται από τρίτους." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Cdrom με Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Cdrom με το Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 'Jaunty Jackalope" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Cdrom με το Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Cdrom με Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Cdrom με Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Cdrom με Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Cdrom με Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Υποστηριζόμενα από την κοινότητα" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Λογισμικό με περιορισμούς" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Cdrom με το Ubuntu 6.10 'Edgy Eft" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 TLS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Λογισμικό ανοικτού κώδικα υποστηριζόμενο από την Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Υποστηριζόμενα από την κοινότητα (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Λογισμικό ανοιχτού κώδικα υποστηριζόμενο από την κοινότητα" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Όχι-ελεύθεροι οδηγοί" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Οδηγοί με κλειστό κώδικα για συσκευές" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Όχι-ελεύθερο (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Λογισμικό με περιορισμούς από πνευματικά δικαιώματα και νόμους" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Cdrom με Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Σημαντικές ενημερώσεις ασφαλείας" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Συνιστώμενες ενημερώσεις" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Προτεινόμενες ενημερώσεις" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Μη υποστηριζόμενες ενημερώσεις" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Cdrom με Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Αναβαθμίσεις ασφαλείας Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Αναβαθμίσεις Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Cdrom με Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Επίσημα υποστηριζόμενο" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Αναβαθμίσεις ασφαλείας Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ενημερώσεις Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Υποστηριζόμενα από την κοινότητα (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Όχι-ελεύθερα (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Cdrom με το Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Δεν υποστηρίζονται πια επίσημα" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Περιορισμένα πνευματικά δικαιώματα" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ενημερώσεις ασφαλείας Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ενημερώσεις Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 Backports" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 'Wheezy' " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 'Squeeze' " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 'Lenny' " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 'Etch'" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 'Sarge'" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Προτεινόμενες ενημερώσεις" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Ενημερώσεις ασφαλείας" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Τρέχουσα σταθερή έκδοση Debian " + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian testing" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian 'Sid' (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Λογισμικό συμβατό με DFSG με μη Ελεύθερες Εξαρτήσεις" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Λογισμικό μη συμβατό με DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Εξυπηρετητής για %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Κύριος εξυπηρετητής" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Προσαρμοσμένοι εξυπηρετητές" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Λήψη αρχείου %(current)li από %(total)li με %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Λήψη αρχείου %(current)li από %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Λεπτομέρειες" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Εκκίνηση..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Ολοκληρώθηκε" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" +"Μη έγκυρος unicode στην περιγραφή για το '%s' (%s). Παρακαλώ αναφέρετέ το." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Η λίστα των αλλαγών δεν είναι διαθέσιμη." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"Η λίστα αλλαγών δεν είναι διαθέσιμη.\n" +"\n" +"Παρακαλώ χρησιμοποιήστε το http://launchpad.net/ubuntu/+source/%s/%s/" +"+changelog\n" +"έως ότου οι αλλαγές γίνουν διαθέσιμες ή προσπαθήστε αργότερα." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Αποτυχία λήψης της λίστας των αλλαγών.\n" +"Παρακαλώ ελέγξτε τη σύνδεση σας στο διαδίκτυο." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Η λίστα των αρχείων για το '%s' δεν μπόρεσε να διαβαστεί" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Η λίστα των αρχείων ελέγχου για το '%s' δεν μπόρεσε να διαβαστεί" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Η εξάρτηση δεν ικανοποιείται: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Συγκρούεται με το εγκατεστημένο πακέτο '%s'" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Παραβιάζει υπάρχον πακέτο '%(pkgname)s' εξάρτηση %(depname)s " +"(%(deprelation)s %(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Παραβιάζει υπάρχον πακέτο '%(pkgname)s' σύγκρουση με : %(targetpkg)s " +"(%(comptype)s %(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Παραβιάζει υπάρχον πακέτο '%(pkgname)s' το οποίο συγκρούεται με: " +"'%(targetpkg)s'. Αλλά το '%(debfile)s', το παρέχει μέσω του: '%(provides)s'" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Δεν βρέθηκε το πεδίο Αρχιτεκτονική στο πακέτο" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Λάθος αρχιτεκτονική '%s'" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Μια πιο πρόσφατη έκδοση είναι ήδη εγκατεστημένη" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Αποτυχία ικανοποίησης όλων των εξαρτήσεων (σπασμένη cache)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "Αδυναμία εγκατάστασης του '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Αυτόματη αποσυμπίεση:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Μετατράπηκε αυτόματα σε εκτυπώσιμο ascii:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"Εγκαταστήστε τις Εξαρτήσεις Μεταγλώττισης για το πηγαίο πακέτο '%s' που " +"δομεί το %s\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Ένα απαραίτητο πακέτα θα πρέπει να απομακρυνθεί" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Ολοκληρώθηκε" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Πιέστε" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Αγν" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Λαθ" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Φέρε:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "[Λειτουργεί]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Αλλαγή μέσου: παρακαλώ τοποθετήστε το δίσκο\n" +" '%s'\n" +"στον οδηγό '%s' και πατήστε enter\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Μεταφέρθηκαν %sB σε %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "Παρακαλώ δώστε ένα όνομα για το Δίσκο, όπως 'Debian 2.1r1 Disk 1'" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Παρακαλώ τοποθετήστε ένα Δίσκο στον οδηγό και πατήστε enter" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Κατασκευή δομών δεδομένων" diff --git a/po/en_AU.po b/po/en_AU.po new file mode 100644 index 0000000..3dc30fb --- /dev/null +++ b/po/en_AU.po @@ -0,0 +1,660 @@ +# English (Australia) translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# David Symons , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:01+0000\n" +"Last-Translator: David Satchell \n" +"Language-Team: English (Australia) \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD-ROM with Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD-ROM with Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD-ROM with Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD-ROM with Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD-ROM with Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD-ROM with Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD-ROM with Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD-ROM with Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD-ROM with Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD-ROM with Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD-ROM with Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Community maintained" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Restricted software" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD-ROM with Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Community maintained Open Source software" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Community maintained (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Community maintained Open Source software" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Non-free drivers" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Proprietary drivers for devices" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Restricted software (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CD-ROM with Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Important security updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Recommended updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Proposed updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Backported updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD-ROM with Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD-ROM with Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Officially supported" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Community maintained (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Non-free (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD-ROM with Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Restricted copyright" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 Backports" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Proposed updates" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Important security updates" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-compatible Software with Non-Free Dependencies" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Non-DFSG-compatible Software" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Server for %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Main server" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Custom servers" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Downloading file %li of %li with %s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Downloading file %li of %li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Details" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "The list of changes is not available" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Failed to download the list of changes. Please check your Internet " +"connection." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Can't install '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "An essential package would have to be removed" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/en_CA.po b/po/en_CA.po new file mode 100644 index 0000000..d272067 --- /dev/null +++ b/po/en_CA.po @@ -0,0 +1,681 @@ +# Canadian English translation for update-manager +# Copyright (C) 2005 Adam Weinberger and the GNOME Foundation +# This file is distributed under the same licence as the update-manager package. +# Adam Weinberger , 2005. +# +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:06+0000\n" +"Last-Translator: Adam Weinberger \n" +"Language-Team: Canadian English \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +#, fuzzy +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 5.04 Updates" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Community maintained (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +#, fuzzy +msgid "Restricted software" +msgstr "Contributed software" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +#, fuzzy +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 5.04 Security Updates" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Community maintained (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Community maintained (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Community maintained (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +#, fuzzy +msgid "Non-free drivers" +msgstr "Non-free (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +#, fuzzy +msgid "Restricted software (Multiverse)" +msgstr "Non-free (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +#, fuzzy +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +#, fuzzy +msgid "Important security updates" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "_Install" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "_Install" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +#, fuzzy +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +#, fuzzy +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +#, fuzzy +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +#, fuzzy +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.04 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +#, fuzzy +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.04 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +#, fuzzy +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +#, fuzzy +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 Security Updates" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +#, fuzzy +msgid "Officially supported" +msgstr "Officially supported" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +#, fuzzy +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +#, fuzzy +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +#, fuzzy +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +#, fuzzy +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 5.04 Security Updates" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Community maintained (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Non-free (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +#, fuzzy +msgid "No longer officially supported" +msgstr "Officially supported" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Restricted copyright" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +#, fuzzy +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 5.04 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +#, fuzzy +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 5.04 Updates" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian Stable Security Updates" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian Stable Security Updates" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian Stable Security Updates" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian Stable Security Updates" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian Stable Security Updates" + +#. Description +#: ../data/templates/Debian.info.in:119 +#, fuzzy +msgid "Proposed updates" +msgstr "_Install" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +#, fuzzy +msgid "Details" +msgstr "Details" + +#: ../apt/progress/gtk2.py:428 +#, fuzzy +msgid "Starting..." +msgstr "Settings" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +#, fuzzy +msgid "The list of changes is not available" +msgstr "There is a new release of Ubuntu available!" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Failed to download changes. Please check if there is an active internet " +"connection." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/eo.po b/po/eo.po new file mode 100644 index 0000000..648006a --- /dev/null +++ b/po/eo.po @@ -0,0 +1,649 @@ +# Esperanto translation for update-manager +# Copyright (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# Ed GLEZ , 2006. +# Aisano < >, 2010. +# Patrick (Petriko) OUDEJANS < >, 2010. +# Roĉjo HUURMAN < >, 2010. +# Michael MORONI < >, 2009, 2011. +# Kristjan SCHMIDT , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2012-06-11 09:54+0000\n" +"Last-Translator: Michael Moroni \n" +"Language-Team: Esperanto \n" +"Language: eo\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2012-06-11 09:56+0000\n" +"X-Generator: Launchpad (build 15376)\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "KD kun Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "KD kun Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "KD kun Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "KD kun Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Partneroj de Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Programaro pakita de Canonical por siaj partneroj" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Ĉi tiu programaro ne estas parto de Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Sendepende" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Ofertitaj de eksteraj programistoj" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Programaro ofertita de eksteraj programistoj" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "KD kun Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "KD kun Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "KD kun Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "KD kun Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "KD kun Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "KD kun Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "KD kun Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Prizorgata de komunumo" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Limigita programaro" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "KD kun Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Libera kaj malfermitkoda programaro subtenata de Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Prizorgata de komunumo (universo)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Libera kaj malfermitkoda programaro prizorgata de komunumo" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Neliberaj peliloj" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Fermitkoda peliloj por aparatoj" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Limigita programaro (multiverso)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Programaro limigita pro kopirajto aŭ leĝaj temoj" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "KD kun Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Gravaj ĝisdatigoj pri sekureco" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Rekomenditaj ĝisdatigoj" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Antaŭ-eldonataj ĝisdatigoj" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Nesubtenataj ĝisdatigoj" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "KD kun Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Sekurecaj ĝisdatigoj de Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ĝisdatigoj de Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Retroportoj de Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "KD kun Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Oficiale subtenata" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Sekurecaj ĝisdatigoj de Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ĝisdatigoj de Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Retroportoj de Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Prizorgata de komunumo (universo)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Mallibera (multiverso)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "KD kun Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Ne plu oficiale subtenata" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Limigita kopirajto" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Sekurecaj ĝisdatigoj de Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ĝisdatigoj de Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Retroportoj de Ubuntu 4.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debiano 7 'Wheezy' " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debiano 6.0 'Squeeze' " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debiano 5.0 'Lenny' " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debiano 4.0 'Etch'" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debiano 3.1 'Sarge'" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Proponitaj ĝisdatigoj" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Sekurecaj ĝisdatigoj" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Aktuala stabila eldono de Debiano" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Testado de Debiano" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debiano 'Sid' (nestabila)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-kongrua programaro kun malliberaj dependecoj" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "DFSG-nekongruaj programaroj" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Servilo por %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Ĉefa servilo" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Propraj serviloj" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Elŝutanta dosieron %(current)li el %(total)li per %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Elŝutanta dosieron %(current)li el %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detaloj" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Komencanta..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Kompleta" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "Nevalida unikodaĵo en priskribo por '%s' (%s). Bonvole raportu." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "La listo de ŝanĝoj ne disponeblas" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"La listo de ŝanĝoj ankoraŭ ne disponeblas.\n" +"\n" +"Bonvole uzu http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"ĝis kiam la ŝanĝoj disponebligos aŭ provu denove poste." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Elŝutado de listo de ŝanĝoj fiaskis. \n" +"Bonvole kontrolu vian interretan konekton." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Listo de dosieroj de '%s' ne legeblas" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Listo de kontroldosieroj por '%s' ne legeblas" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Dependeco ne plenumeblas: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Ĝi konfliktas kun la instalita pakaĵo '%s'" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Ĝi malfunkciigas la dependaĵon %(depname)s (%(deprelation)s %(depversion)s) " +"de la ekzistanta pakaĵo '%(pkgname)s'" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Ĝi malfunkciigas la konflikton de la ekzistanta pakaĵo '%(pkgname)s': " +"%(targetpkg)s (%(comptype)s %(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Ĝi malfunkciigas la ekzistantan pakaĵon '%(pkgname)s' kiu konfliktas kun " +"'%(targetpkg)s' sed la '%(debfile)s' ofertas ĝin per '%(provides)s'" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Neniu kampo pri arĥitekturo en la pakaĵo" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Malkorekta arĥitekturo: '%s'" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Pli nova versio estas jam instalita" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Plenumado de ĉiuj dependecoj fiaskis (difektita kaŝmemoro)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "'%s' ne instaleblas" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Aŭtomate malpakita:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Aŭtomate konvertita al presebla ascii:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "Instali kunmet-dependecojn por fontpakaĵo '%s', kiu kunmetas %s\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Esenca pakaĵo estus forigita" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Farita" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Trafo " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Ign " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Era " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Aki:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [laboranta]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Ŝanĝo de datumportilo: bonvole enmetu la diskon nomatan\n" +" '%s'\n" +"en la diskingon '%s' kaj presu la enigan klavon\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Prenitaj %sB en %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" +"Bonvole provizi nomon al ĉi tiu disko, ekzemple 'Disko 1 de Debiano 2.1r1'" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Bonvole enmetu diskon en la diskingon kaj presu la enigan klavon" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Konstruanta datumstrukturojn" + +#~ msgid "Python-debian module not available" +#~ msgstr "Modulo Python-debian ne haveblas" + +#~ msgid "Community-maintained Open Source software" +#~ msgstr "Komunume prizorgata malfermitkoda programaro" + +#~ msgid "Canonical-supported Open Source software" +#~ msgstr "Malfermitkoda programaro subtenata de Canonical" diff --git a/po/es.po b/po/es.po new file mode 100644 index 0000000..1611319 --- /dev/null +++ b/po/es.po @@ -0,0 +1,663 @@ +# python-apt po translation to Spanish +# Copyright (C) 2004 - 2012 Software in the Public Interest +# This file is distributed under the same license as the python-apt package. +# +# Changes: +# - Initial translation +# 2004 Michiel Sikkes +# Jorge Bernal , 2005. +# Jorge Bernal , 2005. +# - Updates +# Omar Campagne , 2012. +# +# Traductores, si no conocen el formato PO, merece la pena leer la +# documentación de gettext, especialmente las secciones dedicadas a este +# formato, por ejemplo ejecutando: +# info -n '(gettext)PO Files' +# info -n '(gettext)Header Entry' +# +# Equipo de traducción al español, por favor lean antes de traducir +# los siguientes documentos: +# +# - El proyecto de traducción de Debian al español +# http://www.debian.org/intl/spanish/ +# especialmente las notas y normas de traducción en +# http://www.debian.org/intl/spanish/notas +# +# - La guía de traducción de po's de debconf: +# /usr/share/doc/po-debconf/README-trans +# o http://www.debian.org/intl/l10n/po-debconf/README-trans +# +msgid "" +msgstr "" +"Project-Id-Version: python-apt 0.8.5\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2012-06-27 17:24+0200\n" +"Last-Translator: Omar Campagne \n" +"Language-Team: Debian l10n Spanish \n" +"Language: es\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: Virtaal 0.7.1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 «Precise Pangolin»" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Cdrom con Ubuntu 12.04 «Precise Pangolin»" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 «Oneiric Ocelot»" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Cdrom con Ubuntu 11.10 «Oneiric Ocelot»" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 «Natty Narwhal»" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Cdrom con Ubuntu 11.04 «Natty Narwhal»" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 «Maverick Meerkat»" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Cdrom con Ubuntu 10.10 «Maverick Meerkat»" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Socios de Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Software empaquetado por Canonical para sus socios" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Este software no es parte de Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Independiente" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Proporcionado por desarrolladores de software externos" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Software proporcionado por desarrolladores externos." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 «Lucid Lynx»" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Cdrom con Ubuntu 10.04 «Lucid Lynx»" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 «Karmic Koala»" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Cdrom con Ubuntu 9.10 «Karmic Koala»" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 «Jaunty Jackalope»" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Cdrom con Ubuntu 9.04 «Jaunty Jackalope»" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 «Intrepid Ibex»" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Cdrom con Ubuntu 8.10 «Intrepid Ibex»" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 «Hardy Heron»" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Cdrom con Ubuntu 8.04 «Hardy Heron»" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 «Gutsy Gibbon»" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Cdrom con Ubuntu 7.10 «Gutsy Gibbon»" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 «Feisty Fawn»" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Cdrom con Ubuntu 7.04 «Feisty Fawn»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 «Edgy Eft»" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Mantenido por la comunidad" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Software restringido" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Cdrom con Ubuntu 6.10 «Edgy Eft»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS «Dapper Drake»" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Software libre y abierto mantenido por Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Mantenido por la comunidad (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Software libre y abierto mantenido por la comunidad" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Controladores no libres" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Controladores privativos para dispositivos" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Software restringido (multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Software restringido por copyright o cuestiones legales" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Cdrom con Ubuntu 6.06 LTS «Dapper Drake»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Actualizaciones importantes de seguridad" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Actualizaciones recomendadas" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Actualizaciones previas a la publicación" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Actualizaciones de paquetes no oficiales" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 «Breezy Badger»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Cdrom con Ubuntu 5.10 «Breezy Badger»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Actualizaciones de seguridad de Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Actualizaciones de Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "«Backports» de Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 «Hoary Hedgehog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Cdrom con Ubuntu 5.04 «Hoary Hedgehog»" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Soportado oficialmente" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Actualizaciones de seguridad de Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Actualizaciones de Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "«Backports» de Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 «Warty Warthog»" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Mantenido por la comunidad (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Software no libre (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Cdrom con Ubuntu 4.10 «Warty Warthog»" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Sin más soporte oficial" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Copyright restringido" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 Actualizaciones de seguridad" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Actualizaciones de Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "«Backports» de Ubuntu 4.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 «Wheezy» " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 «Squeeze» " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 «Lenny» " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 «Etch»" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 «Sarge»" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Actualizaciones propuestas" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Actualizaciones de seguridad" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Publicación estable actual de Debian" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian testing («en pruebas»)" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian «Sid» («inestable»)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Software compatible con las «DFSG» con dependencias no libres" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Software no compatible con las «DFSG»" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Servidor para %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Servidor principal" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Servidores personalizados" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Descargando archivo %(current)li de %(total)li a %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Descargando archivo %(current)li de %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detalles" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Iniciando..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Completo" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" +"Unicode inválido en la descripción de «%s» (%s). Le rogamos que informe de " +"ello." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "La lista de cambios no se encuentra disponible." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"La lista de cambios aún no está disponible.\n" +"\n" +"Utilice «http://launchpad.net/ubuntu/+source/%s/%s/+changelog»\n" +"hasta que la lista esté disponible o inténtelo en otro momento." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Hubo un fallo al descargar la lista de cambios. \n" +"Por favor, compruebe su conexión a Internet." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "No se ha podido leer la lista de ficheros de «%s»" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "No se ha podido leer la lista de ficheros de control de «%s»" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "No se puede satisfacer la dependencia: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Conflictos con el paquete instalado «%s»" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"La dependencia «%(depname)s» rompe el paquete «%(pkgname)s» (%(deprelation)s " +"%(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Conflicto con el paquete «%(pkgname)s»: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Conflicto con el paquete «%(pkgname)s»: «%(targetpkg)s». Pero «%(debfile)s» " +"lo proporciona mediante «%(provides)s»" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "El paquete no contiene un campo «Architecture»" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Arquitectura no válida «%s»" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Una versión posterior ya está instalada" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Fallo al satisfacer todas las dependencias (caché corrupto)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "No se ha podido instalar «%s»" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Descomprimido automáticamente:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Convertido de forma automática a ASCII imprimible:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"Instale las dependencias de construcción del paquete fuente «%s», que " +"construye «%s»\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Se desinstalaría un paquete esencial" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Finalizado" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Conexión" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Ignorado" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Error" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Obtener:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [En funcionamiento]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Cambio de dispositivo: introduzca el disco denominado\n" +"«%s»\n" +"en el dispositivo «%s» y pulse Intro\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Obtenidos %sB en %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "Proporcione un nombre para este disco, como «Debian 2.1r1 Disco 1»" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Introduzca un disco en el dispositivo y pulse Intro" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Generando estructuras de datos" diff --git a/po/fi.po b/po/fi.po new file mode 100644 index 0000000..ba718ff --- /dev/null +++ b/po/fi.po @@ -0,0 +1,639 @@ +# update-manager's Finnish translation. +# Copyright (C) 2005-2006 Timo Jyrinki +# This file is distributed under the same license as the update-manager package. +# Timo Jyrinki , 2005-2006. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2012-06-11 08:55+0300\n" +"Last-Translator: Timo Jyrinki \n" +"Language-Team: Finnish \n" +"Language: fi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 \"Precise PAngolin\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 \"Precise Pangolin\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 \"Oneiric Ocelot\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 \"Oneiric Ocelot\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 \"Natty Narwhal\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 \"Natty Narwhal\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 \"Maverick Meerkat\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 \"Maverick Meerkat\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Canonicalin partnerit" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Canonicalin pakkaamia partnereiden sovelluksia" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Tämä ohjelma ei ole osa Ubuntua." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Riippumaton" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Muiden kehittäjien sovelluksia" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Kolmansien osapuolien tarjoamia sovelluksia." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 \"Lucid Lynx\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 \"Lucid Lynx\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 \"Karmic Koala\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 \"Karmic Koala\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 \"Jaunty Jackalope\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 \"Jaunty Jackalope\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 \"Intrepid Ibex\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 \"Intrepid Ibex\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 \"Hardy Heron\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 \"Hardy Heron\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 \"Gutsy Gibbon\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 \"Gutsy Gibbon\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 \"Feisty Fawn\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 \"Feisty Fawn\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 \"Edgy Eft\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Yhteisön ylläpitämät" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Rajoitetut ohjelmistot" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 \"Edgy Eft\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS \"Dapper Drake\"" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Canonicalin tukemat vapaat ja avoimen lähdekoodin ohjelmistot" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Yhteisön ylläpitämät (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Yhteisön ylläpitämät vapaat ja avoimen lähdekoodin ohjelmistot" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Ei-vapaat ajurit" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Suljetut laiteajurit" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Käyttörajoitetut ohjelmistot (multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Tekijänoikeus- tai lakiasioilla rajoitetut ohjelmistot" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS \"Dapper Drake\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Tärkeät turvallisuuspäivitykset" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Suositellut päivitykset" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Esijulkaistut päivitykset" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Tukemattomat päivitykset" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 \"Breezy Badger\" -CD-levy" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 turvallisuuspäivitykset" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 päivitykset" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 takaisinsovitukset" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\" -CD-levy" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Virallisesti tuettu" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 turvallisuuspäivitykset" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 päivitykset" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 takaisinsovitukset" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Yhteisön ylläpitämät (universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Ei-vapaat ohjelmistot (multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 \"Warty Warthog\" -CD-levy" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Ei enää virallisesti tuettu" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Rajoitettu käyttöoikeus" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 turvallisuuspäivitykset" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 päivitykset" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 takaisinsovitukset" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 \"Wheezy\" " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 \"Squeeze\" " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 \"Lenny\" " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 \"Etch\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Ehdotetut päivitykset" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Turvallisuuspäivitykset" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Debian stable (tämänhetkinen vakaa julkaisu)" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian testing (testattava)" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (epävakaa)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" +"DFSG-yhteensopivat ohjelmistot joilla riippuvuuksia epävapaisiin ohjelmiin" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "DFSG-epäyhteensopivat ohjelmistot" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Palvelin maalle: %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Pääpalvelin" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Määrittele palvelin" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Noudetaan tiedostoa %(current)li/%(total)li nopeudella %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Noudetaan tiedostoa %(current)li/%(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Yksityiskohdat" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Käynnistetään..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Valmis" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" +"\"%s\":n kuvauksessa virheellinen unicode-merkki %s. Ole hyvä ja raportoi " +"virheestä kehittäjille." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Muutosluettelo ei ole saatavilla." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"Muutosluettelo ei ole vielä saatavilla.\n" +"\n" +"Käytä osoitetta http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"kunnes muutokset tulevat saataville, tai yritä myöhemmin uudelleen." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Muutosluettelon nouto epäonnistui. \n" +"Tarkista Internet-yhteytesi toimivuus." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Kohteen \"%s\" tiedostoluetteloa ei voi lukea" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Kohteen \"%s\" hallintatiedostoja ei voi lukea" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Riippuvuus ei täytettävissä: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Ristiriidassa asennetun paketin \"%s\" kanssa" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Rikkoo olemassa olevan paketin '%(pkgname)s', riippuvuus %(depname)s " +"(%(deprelation)s %(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Rikkoo olemassa olevan paketin '%(pkgname)s', ristiriita: %(targetpkg)s " +"(%(comptype)s %(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Rikkoo olemassa olevan paketin '%(pkgname)s', joka on ristiriidassa " +"seuraavien kanssa: '%(targetpkg)s'. Mutta '%(debfile)s' tarjoaa sen " +"seuraavasti: '%(provides)s'" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Ei Architecture-kenttää paketissa" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Väärä arkkitehtuuri \"%s\"" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Myöhempi versio on jo asennettu" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Kaikkia riippuvuuksia ei voi täyttää (rikkinäinen välimuisti)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "Ei voi asentaa \"%s\"" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Purettu automaattisesti:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Automaattisesti muunnettu tulostettavaksi asciiksi:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"Asenna käännösriippuvuudet (Build-Dependencies) lähdepaketille \"%s\", josta " +"%s rakennetaan\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Välttämätön paketti jouduttaisiin poistamaan" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... valmis" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Osuma " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Ohi " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Vir " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Hae:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [Työskennellään]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Tallennusvälineen vaihto: syötä levy \n" +"\"%s\"\n" +"asemaan ”%s” ja paina Enter\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Noudettu %sB in %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "Syötä nimi tälle levylle, esimerkiksi \"Debian 6.0r2 levy 1\"" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Syötä levy asemaan ja paina Enter" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Kasataan tietorakenteita" diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..6ba61f2 --- /dev/null +++ b/po/fr.po @@ -0,0 +1,652 @@ +# french translation of python-apt +# Copyright (C) 2007 Hugues NAULET +# Copyright (C) 2005, 2007-2010, 2012 Debian French l10n team +# This file is distributed under the same license as the python-apt package. +# +# Jean Privat , 2005. +# Vincent Carriere , 2005. +# Hugues NAULET , 2007-2009. +# Bruno Travouillon , 2010. +# David Prévot , 2012. +msgid "" +msgstr "" +"Project-Id-Version: python-apt 0.7.2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2012-01-12 18:20-0400\n" +"Last-Translator: David Prévot \n" +"Language-Team: French \n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1\n" +"X-Generator: Lokalize 1.2\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 « Precise Pangolin »" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD contenant Ubuntu 12.04 « Precise Pangolin »" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 « Oneiric Ocelot »" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD contenant Ubuntu 11.10 « Oneiric Ocelot »" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 « Natty Narwhal »" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD contenant Ubuntu 11.04 « Natty Narwhal »" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 « Maverick Meerkat »" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD contenant Ubuntu 10.10 « Maverick Meerkat »" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Partenaires de Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Logiciel empaqueté par Canonical pour ses partenaires" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Ce logiciel ne fait pas partie d'Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Indépendant" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Fourni par des développeurs de logiciel tiers" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Logiciel offert par des développeurs de logiciel tiers." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 « Lucid Lynx »" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD contenant Ubuntu 10.04 « Lucid Lynx »" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 « Karmic Koala »" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD contenant Ubuntu 9.10 « Karmic Koala »" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 « Jaunty Jackalope »" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD contenant Ubuntu 9.04 « Jaunty Jackalope »" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 « Intrepid Ibex »" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD contenant Ubuntu 8.10 « Intrepid Ibex »" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 « Hardy Heron »" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD contenant Ubuntu 8.04 « Hardy Heron »" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 « Gutsy Gibbon »" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD contenant Ubuntu 7.10 « Gutsy Gibbon »" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 « Feisty Fawn »" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD contenant Ubuntu 7.04 « Feisty Fawn »" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 « Edgy Eft »" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Maintenu par la communauté" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Logiciel non libre" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD contenant Ubuntu 6.10 « Edgy Eft »" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS « Dapper Drake »" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Logiciel libre maintenu par Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Maintenu par la communauté (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Logiciel libre maintenu par la communauté" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Pilotes non libres" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Pilotes propriétaires de périphériques" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Logiciel non libre (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Logiciel soumis au droit d'auteur ou à des restrictions légales" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CD contenant Ubuntu 6.06 LTS « Dapper Drake »" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Mises à jour de sécurité" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Mises à jour recommandées" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Mises à jour suggérées" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Mises à jour non gérées" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 « Breezy Badger »" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD contenant Ubuntu 5.10 « Breezy Badger »" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Mises à jour de sécurité pour Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Mises à jour pour Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Rétroportages pour Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 « Hoary Hedgehog »" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD contenant Ubuntu 5.04 « Hoary Hedgehog »" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Officiellement pris en charge" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Mises à jour de sécurité pour Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Mises à jour pour Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Rétroportages pour Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 « Warty Warthog »" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Maintenu par la communauté (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Non libre (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD contenant Ubuntu 4.10 « Warty Warthog »" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Suivi officiel terminé" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Copyright restreint" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Mises à jour de sécurité pour Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Mises à jour pour Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Rétroportages pour Ubuntu 4.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 « Wheezy »" + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 « Squeeze »" + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 « Lenny »" + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 « Etch »" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 « Sarge »" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Mises à jour suggérées" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Mises à jour de sécurité" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Debian stable actuelle" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian « Lenny » (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian « Sid » (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" +"Logiciel libre (selon les principes du projet Debian) dont les dépendances " +"ne sont pas libres" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Logiciel non libre (selon les principes du projet Debian)" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Serveur pour %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Serveur principal" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Serveurs personnalisés" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Téléchargement du fichier %(current)li sur %(total)li à %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Téléchargement du fichier %(current)li sur %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Détails" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Démarrage…" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Terminé" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" +"Unicode incorrect dans la description de « %s » (%s). Merci de le signaler." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "La liste des modifications n'est pas disponible" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"La liste des modifications n'est pas encore disponible.\n" +"\n" +"Veuillez utiliser http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"jusqu'à ce que les changements soient disponibles ou essayer plus tard." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Échec lors du téléchargement de la liste des modifications. \n" +"Veuillez vérifier votre connexion Internet." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "La liste des fichiers pour « %s » ne peut pas être lue" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "La liste des fichiers de contrôle pour « %s » ne peut pas être lue" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "La dépendance ne peut être satisfaite : %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Conflit avec le paquet installé « %s »" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Casse le paquet existant « %(pkgname)s » à cause de sa dépendance " +"%(depname)s (%(deprelation)s %(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Casse le paquet existant « %(pkgname)s » car en conflit avec %(targetpkg)s " +"(%(comptype)s %(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Casse le paquet existant « %(pkgname)s » car en conflit avec %(targetpkg)s. " +"Mais le « %(debfile)s » le fournit à l'aide de « %(provides)s »" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Aucun champ Architecture dans ce paquet" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Architecture « %s » incorrecte" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Une version plus récente est déjà installée" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Impossible de résoudre les dépendances, le cache est corrompu." + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "Impossible d'installer « %s »" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Décompression automatique :\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Conversion automatique en ASCII affichable :\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"Installation des dépendances de construction pour le paquet source « %s » " +"qui compile %s\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Un paquet essentiel devrait être désinstallé" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s… Terminé" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Att " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Ign " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Err " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Prendre :" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [En cours]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Changement de support : veuillez insérer le disque nommé\n" +" « %s »\n" +"dans le lecteur « %s » et appuyer sur entrée\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "%s o téléchargés en %s (%s o/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" +"Veuillez fournir le nom de ce disque, par exemple « Debian 2.1r1 disque 1 »" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Veuillez insérer un disque dans le lecteur et appuyer sur entrée" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Construction des structures de données" + +#~ msgid "Python-debian module not available" +#~ msgstr "Module Python-debian non disponible" + +#~ msgid "This is not a valid DEB archive, missing '%s' member" +#~ msgstr "" +#~ "Ce n'est pas une archive « DEB » valide, le membre « %s » est absent" diff --git a/po/gl.po b/po/gl.po new file mode 100644 index 0000000..505ccc2 --- /dev/null +++ b/po/gl.po @@ -0,0 +1,661 @@ +# translation of gl.po to galician +# translation of update-manager-gl.po to galician +# This file is distributed under the same license as the update-manager package. +# Copyright (c) 2004 Canonical +# 2004 Michiel Sikkes +# Mar Castro , 2006. +# +msgid "" +msgstr "" +"Project-Id-Version: gl\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-19 00:43+0000\n" +"Last-Translator: Felipe Gil Castiñeira \n" +"Language-Team: galician\n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.10.2\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Actualizacións de Seguranza para Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Cdrom con Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Cdrom con Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Cdrom con Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Cdrom con Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Cdrom con Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Cdrom con Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Cdrom con Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Cdrom con Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Cdrom con Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Actualizacións de Seguranza para Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Cdrom con Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Actualizacións de Seguranza para Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Cdrom con Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 \"Edgy Eft\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Mantido pola Comunidade" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Aplicacións restrinxidas" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Cdrom con Ubuntu 6.10 \"Edgy Eft\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS \"Dapper Drake\"" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Software de Código Aberto soportado por Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Mantido pola Comunidade (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Software de Código Aberto mantido pola Comunidade" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Controladores non libres" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Controladores propietarios de dispositivos" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Software restrinxido (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Software restrinxido por razóns de copyright ou legais" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Cdrom con Ubuntu 6.06 LTS \"Dapper Drake\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Actualizacións de seguranza importantes" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Actualizacións recomendadas" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Actualizacións aconselladas" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Actualizacións de backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "CD con Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Cdrom con Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Actualizacións de seguranza de Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Actualizacións de Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Actualizacións de Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Cdrom con Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Soportado oficialmente" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Actualizacións de Seguranza para Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Actualizacións para Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Backports para Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Mantido pola comunidade (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Software non libre (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Cdrom con Ubuntu 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Xa non se mantén oficialmente" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Copyright restrinxido" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Actualizacións de seguranza de Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Actualizacións de Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Backports para Ubuntu 4.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Actualizacións aconselladas" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Actualizacións de seguranza importantes" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (probas)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (inestable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Software compatible coa DFSG con dependencias non libres" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Software non compatible coa DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Servidor desde %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Servidor principal" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Servidores personalizados" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "A descargar o ficheiro %(current)li de %(total)li con %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "A descargar o ficheiro %(current)li de %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detalles" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Non se dispón da lista de cambios" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Non se puido descargar a lista de cambios.\n" +"Comprobe a súa conexión á Internet." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Non se puido instalar '%s»" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Tívose que desinstalar un paquete esencial" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/he.po b/po/he.po new file mode 100644 index 0000000..6942f56 --- /dev/null +++ b/po/he.po @@ -0,0 +1,667 @@ +# translation of update-manager.HEAD.po to Hebrew +# This file is distributed under the same license as the PACKAGE package. +# Yuval Tanny, 2005. +# Yuval Tanny, 2005. +# Yuval Tanny, 2005. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Yuval Tanny, 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager.HEAD\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 08:48+0000\n" +"Last-Translator: Yaniv Abir \n" +"Language-Team: Hebrew \n" +"Language: he\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: KBabel 1.10.2\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "עדכוני אבטחה - אובונטו 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "תקליטור אובונטו 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "אובונטו 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "תקליטור אובונטו 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "אובונטו 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "תקליטור אובונטו 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "אובונטו 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "תקליטור אובונטו 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "אובונטו 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "תקליטור אובונטו 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "אובונטו 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "תקליטור אובונטו 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "אובונטו 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "תקליטור אובונטו 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "אובונטו 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "תקליטור אובונטו 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "אובונטו 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "תקליטור אובונטו 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "עדכוני אבטחה - אובונטו 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "תקליטור אובונטו 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "עדכוני אבטחה - אובונטו 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "תקליטור אובונטו 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "אובונטו 6.10 \"Edgy Eft\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "מתוחזק ע\"י הקהילה" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "תוכנה בעלת הגבלות" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "תקליטור אובונטו 6.10 \"Edgy Eft\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "אובונטו 6.06 LTS \"DapperDrake\"" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "תוכנות קוד פתוח הנתמכות ע\"י Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "מתוחזק ע\"י הקהילה (Universe(" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "תוכנות קוד פתוח המתוחזקות ע\"י הקהילה" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "דרייברים לא חופשיים" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "דרייברים קניינים להתקנים" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "תוכנה בעלת הגבלות (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "תקליטור אובונטו 6.06 LTS \"Dapper Drake\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "עדכוני אבטחה חשובים" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "עדכונים מומלצים" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "עדכונים מוצעים" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "עדכונים מוצעים" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "אובונטו 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "תקליטור אובונטו 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "עדכוני אבטחה - אובונטו 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "עדכונים - אובונטו 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +#, fuzzy +msgid "Ubuntu 5.10 Backports" +msgstr "עדכונים - אובונטו 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "אובונטו 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "תקליטור אובונטו 5.04 \"Hoary Hedgehog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "נתמך רשמית" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "עדכוני אבטחה - אובונטו 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "עדכונים - אובונטו 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +#, fuzzy +msgid "Ubuntu 5.04 Backports" +msgstr "עדכונים - אובונטו 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "אובונטו 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "מתוחזק ע\"י קהילה (Universe(" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "לא-חופשי (Multiverse(" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "תקליטור אובונטו 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "אינה נתמכת רשמית יותר" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "זכויות יוצרים מגבילות" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "עדכוני אבטחה - אובונטו 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "עדכונים - אובונטו 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +#, fuzzy +msgid "Ubuntu 4.10 Backports" +msgstr "עדכונים - אובונטו 5.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "דביאן 3.1 \"סארג'\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "דביאן 3.1 \"סארג'\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "דביאן בדיקה" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "דביאן בדיקה" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "דביאן 3.1 \"סארג'\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "עדכונים מוצעים" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "עדכוני אבטחה חשובים" + +#. Description +#: ../data/templates/Debian.info.in:133 +#, fuzzy +msgid "Debian current stable release" +msgstr "דביאן לא יציב \"סיד\"" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "דביאן בדיקה" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "דביאן לא ארה\"ב (לא יציב)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "השרת ב%s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "שרת ראשי" + +#: ../aptsources/distro.py:250 +#, fuzzy +msgid "Custom servers" +msgstr "השרת הקרוב ביותר" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "מוריד קובץ %li מתוך %li ב-%s לשנייה" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "מוריד קובץ %li מתוך %li ב-%s לשנייה" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "פרטים" + +#: ../apt/progress/gtk2.py:428 +#, fuzzy +msgid "Starting..." +msgstr "הגדרות" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "רשימת השינויים אינה זמינה" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "נכשל בהורדת רשימת השינויים. אנא בדוק אם החיבור לאינטרנט עובד." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "לא ניתן להתקין את \"%s\"" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "חבילה חיונית תוסר בלית ברירה" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/hr.po b/po/hr.po new file mode 100644 index 0000000..66c76e3 --- /dev/null +++ b/po/hr.po @@ -0,0 +1,660 @@ +# Croatian translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-18 19:37+0000\n" +"Last-Translator: Ante Karamatić \n" +"Language-Team: Croatian \n" +"Language: hr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.04 sigurnosne nadogradnje" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CDROM s Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 'Wart Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Cdrom sa Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Wart Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Cdrom sa Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Wart Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Cdrom sa Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Cdrom sa Ubuntu 5.04 ' Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Wart Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Cdrom sa Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Wart Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Cdrom sa Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Cdrom sa Ubuntu 5.04 ' Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Cdrom sa Ubuntu 5.04 ' Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.04 sigurnosne nadogradnje" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CDROM s Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.04 sigurnosne nadogradnje" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CDROM s Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Održavani od strane zajednice" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Neslobodni softver" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CDROM sa Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Službeno podržani Open Source softver" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Održavani od strane zajednice (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Softver održavan od strane zajednice" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Neslobodni pogonski programi" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Neslobodni upogonitelji za uređaje" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Ograničeni softver (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Softver ograničen autorskim pravom ili legalnim pitanjima" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CDROM s Ubuntu 6.06 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Važne sigurnosne nadogradnje" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Preporučene nadogradnje" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Predložene nadogradnje" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Backport nadogradnje" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CDROM s Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 sigurnosne nadogradnje" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 osvježenja" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 backporti" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Cdrom sa Ubuntu 5.04 ' Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Službeno podržani" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 sigurnosne nadogradnje" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 nadogradnje" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 backporti" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Wart Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Održavani od strane zajednice (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Neslobodni (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Cdrom sa Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Više nisu službeno podržani" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Ograničeno autorsko pravo" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 sigurnosne nadogradnje" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 osvježenja" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 backports" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Predložene nadogradnje" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Važne sigurnosne nadogradnje" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (testni)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (nestabilni)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-kompatibilni programi sa neslobodnim ovisnostima" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "DFSG-nekompatibilni programi" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Poslužitelj za %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Glavni poslužitelj" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Osobni poslužitelji" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Preuzimanje datoteke %(current)li od %(total)li brzinom %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Preuzimam datoteku %(current)li od %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detalji" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Popis promjena nije dostupan." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Preuzimanje popisa promjena nije uspjelo. \n" +"Molim, provjerite svoju internet vezu." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Ne mogu instalirati '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Bitan paket bi morao biti uklonjen" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/hu.po b/po/hu.po new file mode 100644 index 0000000..8045f25 --- /dev/null +++ b/po/hu.po @@ -0,0 +1,647 @@ +# Hungarian translation of update-manager +# This file is distributed under the same license as the update-manager package. +# Copyright (C) 2005, 2007, Free Software Foundation, Inc. +# +# Gabor Kelemen , 2005, 2007. +msgid "" +msgstr "" +"Project-Id-Version: update-manager.HEAD\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2012-06-11 18:21+0000\n" +"Last-Translator: Gabor Kelemen \n" +"Language-Team: Hungarian \n" +"Language: hu\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2012-06-11 18:32+0000\n" +"X-Generator: Launchpad (build 15376)\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 „Precise Pangolin”" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Az Ubuntu 12.04 „Precise Pangolin”-t tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 „Oneiric Ocelot”" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Az Ubuntu 11.10 „Oneiric Ocelot”-ot tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 „Natty Narwhal”" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Az Ubuntu 11.04 „Natty Narwhal”-t tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 „Maverick Meerkat”" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Az Ubuntu 10.10 „Maverick Meerkat”-ot tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Canonical partnerek" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "A Canonical által partnereinek csomagolt szoftverek" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Ezek a szoftverek nem részei az Ubuntunak." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Független" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Külső szoftverfejlesztők által biztosított" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Külső szoftverfejlesztők által biztosított szoftverek." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 „Lucid Lynx”" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Az Ubuntu 10.04 „Lucid Lynx”-et tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 „Karmic Koala”" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Az Ubuntu 9.10 „Karmic Koala”-t tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 „Jaunty Jackalope”" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Az Ubuntu 9.04 „Jaunty Jackalope”-ot tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 „Intrepid Ibex”" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Az Ubuntu 8.10 „Intrepid Ibex”-et tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 „Hardy Heron”" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Az Ubuntu 8.04 „Hardy Heron”-t tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 „Gutsy Gibbon”" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Az Ubuntu 7.10 „Gutsy Gibbon”-t tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 „Feisty Fawn”" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Az Ubuntu 7.04 „Feisty Fawn”-t tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 „Edgy Eft”" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Közösségi karbantartású" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Nem-szabad" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Az Ubuntu 6.10 „Edgy Eft” CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS „Dapper Drake”" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "A Canonical által támogatott szabad és nyílt forrású szoftverek" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Közösségi karbantartású (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "A közösség által karbantartott szabad és nyílt forrású szoftverek" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Nem-szabad meghajtók" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Szabadalmazott eszközmeghajtók" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Nem-szabad szoftverek (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Szerzői vagy egyéb jogi problémák miatt korlátozott szoftver" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Az Ubuntu 6.06 LTS „Dapper Drake”-et tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Fontos biztonsági frissítések" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Ajánlott frissítések" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Előzetesen kiadott frissítések" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Nem támogatott frissítések" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Az Ubuntu 5.10 „Breezy Badger”-t tartalmazó CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 biztonsági frissítések" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 frissítések" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 visszaportolt csomagok" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 „Hoary Hedgehog”" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Az Ubuntu 5.04 „Hoary Hedgehog”-ot tartalmazó CD-ROM" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Hivatalosan támogatott" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 biztonsági frissítések" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 frissítések" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 visszaportolt csomagok" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 „Warty Warthog”" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Közösségi karbantartású (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Nem-szabad (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Az Ubuntu 4.10 „Warty Warthog”-ot tartalmazó CD-ROM" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Hivatalosan már nem támogatott" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Szerzői jogi korlátozás alatt" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 biztonsági frissítések" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 frissítések" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 visszaportolt csomagok" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 „Wheezy” " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 „Squeeze” " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 „Lenny” " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 „Etch”" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 „Sarge”" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Javasolt frissítések" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Biztonsági frissítések" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Jelenlegi stabil Debian kiadás" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian – tesztelés alatt" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian „Sid” (instabil)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-kompatibilis szoftver nem-szabad függőségekkel" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Nem DFSG-kompatibilis szoftver" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Kiszolgáló a következőhöz: %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Fő kiszolgáló" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Egyéni kiszolgálók" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" +"%(current)li. fájl letöltése, összesen: %(total)li, sebesség: %(speed)s/mp" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "%(current)li. fájl letöltése, összesen: %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Részletek" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Indítás…" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Kész" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" +"Érvénytelen unicode karakter a(z) „%s” leírásában (%s). Kérem jelentse." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "A módosítások listája nem érhető el" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"A változtatások listája még nem érhető el.\n" +"\n" +"Használja a http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"oldalt, míg nem válik hozzáférhetővé, vagy próbálja meg később." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"A módosítások listájának letöltése meghiúsult.\n" +"Ellenőrizze az internetkapcsolatát." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "„%s” fájljainak listája nem olvasható" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "„%s” vezérlőfájljainak listája nem olvasható" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "A következő függőség nem elégíthető ki: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Ütközik a következő telepített csomaggal: „%s”" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"„%(pkgname)s” csomag törik „%(depname)s” függősége által (%(deprelation)s " +"%(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Megsérti a meglévő „%(pkgname)s” csomag függőségeit; ütközés: %(targetpkg)s " +"(%(comptype)s %(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Megsérti a meglévő „%(pkgname)s” csomag függőségeit; ütközés: " +"„%(targetpkg)s”. Azonban a(z) „%(debfile)s” biztosítja ezen keresztül: " +"„%(provides)s”" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "A csomagban nincs Architecture mező" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Rossz architektúra: „%s”" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Már telepítve van egy újabb verzió" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Nem elégíthető ki minden függőség (a gyorsítótár sérült)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "„%s” nem telepíthető" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Automatikusan kibontva:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Automatikusan nyomtatható ascii-vé konvertálva:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"„%s” csomag fordítási függőségeinek telepítése, ami a(z) %s csomagot építi\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Egy alapvető csomag törlődne" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Kész" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Találat " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Mellőz " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Hiba " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Letöltés:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [Folyamatban]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Helyezze be a(z)\n" +" „%s”\n" +"címkéjű lemezt a(z) %s meghajtóba, és nyomja meg az Entert\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "%sB letöltve %s alatt (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "Adja meg a lemez nevét, például „Debian 2.1r1 1. lemez”" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Helyezzen be egy lemezt a meghajtóba, és nyomja meg az Entert" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Adatstruktúrák építése" + +#~ msgid "Community-maintained Open Source software" +#~ msgstr "Közösségi karbantartású nyílt forrású szoftverek" + +#~ msgid "Canonical-supported Open Source software" +#~ msgstr "A Canonical által támogatott nyílt forrású szoftverek" + +#~ msgid "Python-debian module not available" +#~ msgstr "A Python-debian modul nem érhető el" diff --git a/po/id.po b/po/id.po new file mode 100644 index 0000000..5698096 --- /dev/null +++ b/po/id.po @@ -0,0 +1,638 @@ +# Indonesian translation for python-apt +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the python-apt package. +# Andy Apdhani , 2006. +# Andika Triwidada , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: python-apt\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2012-06-11 01:59+0700\n" +"Last-Translator: Andika Triwidada \n" +"Language-Team: Indonesian \n" +"Language: id\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Poedit-Language: Indonesian\n" +"X-Poedit-Country: INDONESIA\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Cdrom dengan Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Cdrom dengan Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Cdrom dengan Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Cdrom dengan Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Partner Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Perangkat lunak yang dipaketkan oleh Canonical bagi partner mereka" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Perangkat lunak ini bukan bagian dari Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Independen" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Disediakan oleh para pengembang perangkat lunak pihak ketiga" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Perangkat lunak ditawarkan oleh para pengembang pihak ketiga." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Cdrom dengan Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Cdrom dengan Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Cdrom dengan Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Cdrom dengan Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Cdrom dengan Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Cdrom dengan Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Cdrom dengan Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Dikelola oleh komunitas" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Perangkat lunak terbatas" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Cdrom dengan Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Perangkat lunak open-source dan bebas yang didukung oleh Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Dikelola oleh komunitas (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Perangkat lunak open-source dan bebas yang dikelola oleh komunitas" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Driver tidak-bebas" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Driver proprietary bagi perangkat" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Perangkat lunak terbatas (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Perangkat lunak yang terbatas karena masalah hak cipta atau hukum" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Cdrom dengan Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Pemutakhiran keamanan penting" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Pemutakhiran yang disarankan" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Pemutakhira prarilis" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Pemutakhiran yang tak didukung" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Cdrom dengan Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Pemutakhiran Keamanan Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Pemutakhiran Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Backport" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Cdrom dengan Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Resmi didukung" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Pemutakhiran Keamanan Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Pemutakhiran Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 Backport" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Dikelola oleh komunitas (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Tidak-bebas (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Cdrom dengan Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Tak lagi didukung secara resmi" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Hak cipta terbatas" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Pemutakhiran Keamanan Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Pemutakhiran Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 Backport" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 'Wheezy' " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 'Squeeze' " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 'Lenny' " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 'Etch'" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 'Sarge'" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Pemutakhiran yang diusulkan" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Pemutakhiran keamanan" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Rilis stabil Debian saat ini" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian testing" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian 'Sid' (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" +"Perangkat lunak yang kompatibel dengan DFSG tapi tergantung pada Perangkat " +"Lunak Tidak-Bebas" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Perangkat Lunak yang tidak kompatibel dengan DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Server untuk %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Server utama" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Server gubahan" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Mengunduh berkas %(current)li dari %(total)li dalam %(speed)s/dt" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Mengunduh berkas %(current)li dari %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Rincian" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Memulai..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Komplit" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "Unicode tak valid dalam deskripsi bagi '%s' (%s). Mohon laporkan." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Senarai dari perubahan tak tersedia" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"Senarai perubahan belum tersedia.\n" +"\n" +"Silakan pakai http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"sampai perubahan menjadi tersedia atau coba lagi nanti" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Gagal mengunduh senarai dari perubahan. \n" +"Silakan periksa koneksi Internet Anda." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Senarai berkas bagi '%s' tak dapat dibaca" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Senarai berkas kendali bagi '%s' tak dapat dibaca" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Kebergantungan tak dapat dipenuhi: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Konflik dengan paket terpasang '%s'" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Merusak kebergantungan %(depname)s (%(deprelation)s %(depversion)s) dari " +"paket '%(pkgname)s' yang telah ada" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Merusak paket '%(pkgname)s' yang telah ada, konflik: %(targetpkg)s " +"(%(comptype)s %(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Merusak paket '%(pkgname)s' yang telah ada, yang konflik: %(targetpkg)s. " +"Tapi '%(debfile)s' menyediakannya melalui: '%(provides)s'" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Tak ada ruas Architecture dalam paket" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Arsitektur '%s' salah" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Versi lebih baru telah terpasang" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Gagal memenuhi semua kebergantungan (singgahan rusak)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "Tak bisa memasang '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Membuka kompresi secara otomatis:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Otomatis dikonversi ke ascii yang dapat dicetak:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "Memasang Build-Dependencies bagi paket sumber '%s' yang membangun %s\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Paket esensial akan dihapus" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Usai" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Hit " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Ign " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Err " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Ambil:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [Bekerja]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Media berubah: mohon masukkan cakram berlabel\n" +"'%s'\n" +"ke drive '%s' dan tekan enter\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Diambil %sB dalam %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "Mohon beri nama Cakram ini, seperti misalnya 'Debian 2.1r1 Disk 1'" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Mohon masukkan Cakram ke dalam drive dan menekan enter" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Membangun struktur data" diff --git a/po/it.po b/po/it.po new file mode 100644 index 0000000..2981eb3 --- /dev/null +++ b/po/it.po @@ -0,0 +1,662 @@ +# Italian translation for update-manager +# Copyright (c) (c) 2005 Canonical Ltd, and Rosetta Contributors 2005 +# This file is distributed under the same license as the update-manager package. +# Fabio Marzocca , 2005. +# +# +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-22 10:13+0000\n" +"Last-Translator: Luca Ferretti \n" +"Language-Team: Italian \n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.04 - Aggiornamenti di sicurezza" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD-ROM con Ubuntu 5.10 «Breezy Badger»" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD-ROM con Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD-ROM con Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD-ROM con Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 «Hoary Hedgehog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD-ROM con Ubuntu 5.04 «Hoary Hedgehog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD-ROM con Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD-ROM con Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 «Hoary Hedgehog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD-ROM con Ubuntu 5.04 «Hoary Hedgehog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 «Hoary Hedgehog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD-ROM con Ubuntu 5.04 «Hoary Hedgehog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.04 - Aggiornamenti di sicurezza" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD-ROM con Ubuntu 5.10 «Breezy Badger»" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.04 - Aggiornamenti di sicurezza" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD-ROM con Ubuntu 5.10 «Breezy Badger»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 «Edgy Eft»" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Mantenuto dalla comunità" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Software con restrizioni" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD-ROM con Ubuntu 6.10 «Edgy Eft»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS «Dapper Drake»" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Software open source supportato da Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Mantenuto dalla comunità (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Software open source mantenuto dalla comunità" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Driver non liberi" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Driver proprietari per i dispositivi" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Software con restrizioni (multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Software con restrizioni per copyright o motivi legali" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CD-ROM con Ubuntu 6.06 LTS «Drapper Drake»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Aggiornamenti di sicurezza importanti" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Aggiornamenti raccomandati" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Aggiornamenti proposti" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Aggiornamenti di backport" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD-ROM con Ubuntu 5.10 «Breezy Badger»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 - Aggiornamenti di sicurezza" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 - Aggiornamenti" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Backport di Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 «Hoary Hedgehog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD-ROM con Ubuntu 5.04 «Hoary Hedgehog»" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Supportati ufficialmente" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 - Aggiornamenti di sicurezza" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 - Aggiornamenti" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Backport per Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 «Warty Warthog»" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Mantenuti dalla comunità (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Non libero (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD-ROM con Ubuntu 4.10 «Warty Warthog»" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Software non più supportato ufficialmente" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Copyright con restrizioni" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 - Aggiornamenti di sicurezza" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Aggiornamenti di Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Backport per Ubuntu 4.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Aggiornamenti proposti" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Aggiornamenti di sicurezza importanti" + +#. Description +#: ../data/templates/Debian.info.in:133 +#, fuzzy +msgid "Debian current stable release" +msgstr "Debian Unstable" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (Unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Software compatibile con le DFSG con dipendenze non libere" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Software non compatibile con le DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Server in %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Server principale" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Server personalizzati" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Scaricamento del file %(current)li di %(total)li a %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Scaricamento del file %(current)li di %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Dettagli" + +#: ../apt/progress/gtk2.py:428 +#, fuzzy +msgid "Starting..." +msgstr "Impostazioni" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "L'elenco dei cambiamenti non è disponibile" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Fallito lo scaricamento dell'elenco dei cambiamenti. \n" +"Verificare la connessione a Internet." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Impossibile installare \"%s\"" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Un pacchetto essenziale dovrebbe essere rimosso" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/ja.po b/po/ja.po new file mode 100644 index 0000000..2a3b033 --- /dev/null +++ b/po/ja.po @@ -0,0 +1,640 @@ +# Ubuntu-ja translation of update-manager. +# Copyright (C) 2006 THE update-manager'S COPYRIGHT HOLDER +# This file is distributed under the same license as the update-manager package. +# Kenshi Muto , 2007-2012 +# Ikuya Awashiro , 2006. +# Hiroyuki Ikezoe , 2005 +# +# +msgid "" +msgstr "" +"Project-Id-Version: python-apt 0.8.4\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2012-06-30 23:02+0900\n" +"Last-Translator: Kenshi Muto \n" +"Language-Team: Ubuntu Japanese Team \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 'Precise Pangolin' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 'Oneiric Ocelot' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 'Natty Narwhal' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Canonical パートナー" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Canonical によってそのパートナーのためにパッケージされたソフトウェア" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "このソフトウェアは Ubuntu の構成要素ではありません。" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "独立" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "サードパーティのソフトウェア開発者によって提供されたもの" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "サードパーティ開発者によって提供されたソフトウェアです。" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 'Jaunty Jackalope' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 'Intrepid Ibex' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 'Hardy Heron' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 'Gutsy Gibbon' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 'Feisty Fawn' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "コミュニティによるメンテナンス" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "制限のあるソフトウェア" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Canonical によってサポートされるフリー/オープンソースソフトウェア" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "コミュニティによるメンテナンス (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "" +"コミュニティによってメンテナンスされるフリー/オープンソースソフトウェア" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "フリーではないドライバ" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "デバイス用のプロプライエタリなドライバ" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "制限されたソフトウェア (Multiuniverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "著作権もしくは法的な問題によって制限されたソフトウェア" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "重要なセキュリティアップデート" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "推奨アップデート" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "プレリリースされたアップデート" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "サポートされていないアップデート" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger' の CD-ROM" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 セキュリティアップデート" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 アップデート" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 バックポート" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog' の CD-ROM" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "公式なサポート対象" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 セキュリティアップデート" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 アップデート" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 バックポート" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "コミュニティによるメンテナンス (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "フリーではない (Multiuniverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog' の CD-ROM" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "もう公式にサポートされません" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "制限された著作権" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 セキュリティアップデート" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 アップデート" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 バックポート" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 'Wheezy' " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 'Squeeze' " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 'Lenny' " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 'Etch'" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 'Sarge'" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "提案されたアップデート" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "セキュリティアップデート" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Debian の現安定版" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian テスト版" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian 'Sid' (不安定版)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "フリーではないものに依存関係のある DFSG 適合ソフトウェア" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "DFSG に適合しないソフトウェア" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "%s のサーバ" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "メインサーバ" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "カスタムサーバ" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" +"%(total)li 個のファイル中 %(current)li 個を %(speed)s/秒でダウンロードしてい" +"ます" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "%(total)li 個のファイル中 %(current)li 個をダウンロードしています" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "詳細" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "開始しています..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "完了" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "'%s' の説明に無効な Unicode 文字があります (%s)。報告してください。" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "変更の一覧を利用できません" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"変更の一覧がまだ利用できません。\n" +"\n" +"変更が利用できるようになるまで http://launchpad.net/ubuntu/+source/%s/%s/" +"+changelog\n" +"を使用するか、後で再試行してください。" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"変更の一覧のダウンロードに失敗しました。\n" +"インターネット接続を確認してください。" + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "'%s' のファイルの一覧を読み取れませんでした" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "'%s' の control ファイルの一覧を読み取れませんでした" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "依存関係が満たされていません: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "インストール済みパッケージ '%s' と競合" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"既存のパッケージ '%(pkgname)s の依存関係 %(depname)s (%(deprelation)s " +"%(depversion)s) を壊します" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"%(targetpkg)s (%(comptype)s %(targetver)s) と競合する既存のパッケージ " +"'%(pkgname)s' を壊します" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"'%(targetpkg)s' と競合する既存のパッケージ '%(pkgname)s' を壊します。しか" +"し、'%(debfile)s' は '%(provides)s' を通じて提供されます。" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "パッケージに Architecture 欄がありません" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "無効なアーキテクチャ '%s'" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "より新しいバージョンがすでにインストール済みです" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "すべての依存関係を満たすことに失敗しました (キャッシュの破損)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "'%s' をインストールできません" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"自動的に圧縮されました:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "自動で表示可能なアスキー文字に変換されました:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "ソースパッケージ '%s' (%s をビルド) のビルド依存関係をインストール\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "必須パッケージが削除されます" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... 完了" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "ヒット:" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "無視:" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "エラー:" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "取得:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [作業中]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"メディアの変更: '%s'\n" +"のラベルのディスクをドライブ '%s' に挿入し、\n" +"Enter キーを押してください。\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "%sバイト/%s を取得しました (%sB/秒)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "このディスクの名前を入力してください (例: 'Debian 2.1r1 Disk 1')。" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "ディスクをドライブに挿入して、Enter キーを押してください" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "データ構造を構築しています" diff --git a/po/ka.po b/po/ka.po new file mode 100644 index 0000000..d2844a6 --- /dev/null +++ b/po/ka.po @@ -0,0 +1,661 @@ +# translation of update-manager.po to Georgian +# Georgian translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# +# FIRST AUTHOR , 2006. +# Vladimer Sichinava , 2006. +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-18 01:28+0000\n" +"Last-Translator: Malkhaz Barkalaya \n" +"Language-Team: Georgian \n" +"Language: ka\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: KBabel 1.11.2\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.04 უსაფრთხოების განახლება" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.10 'Breezy Badger'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 'Warty Warthog'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Warty Warthog'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Warty Warthog'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Warty Warthog'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Warty Warthog'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.04 უსაფრთხოების განახლება" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.10 'Breezy Badger'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.04 უსაფრთხოების განახლება" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.10 'Breezy Badger'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "universe საზოგადოების მხრდაჭერით" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "არათავისუფალი პროგრამები" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'-ს ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "თავისუფალი პროგრამები (Open Source) Canonical-ის მხარდაჭერით" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "universe საზოგადოების მხრდაჭერით" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "თავისუფალი პროგრამები (Open Source) universe საზოგადოების მხარდაჭერით" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "არათავისუფალი დრაივერები" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "მოწყობილობების საკუთარი დრაივერები" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "არათავისუფალი პროგრამები (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "პატენტებითა და კანონებით შეზღუდული პროგრამები" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "უსაფრთხოების მნიშვნელოვანი განახლებები" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "რეკომენდებული განახლებები" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "შემოთავაზებული განახლებები" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Backport-განახლებები" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'-ის ლაზერული დისკი" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 უსაფრთხოების განახლება" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 განახლებები" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 ბექპორტები" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'-ის ლაზერული დისკი" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "ოფიციალური მხარდაჭერით" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 უსაფრთხოების განახლება" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 განახლებები" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 ბექპორტები" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "საზოგადოების მხარდაჭერით (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "არათავისუფალი (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'-ის ლაზერული დისკი" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "მოხსნილი აქვს ოფიციალური მხარდაჭერა" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "შეზღუდული საავტორო უფლება" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 უსაფრთხოების განახლებები" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 განახლებები" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 ბექპორტები" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "შემოთავაზებული განახლებები" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "უსაფრთხოების მნიშვნელოვანი განახლებები" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "არათავისუფალ პროგრამებზე დამოკიდებული DFSG-თავსებადი პროგრამები" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "DFSG-არათავსებადი პროგრამები" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "%s სერვერი" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "მთავარი სერვერი" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "საკუთარი სერვერები" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "მე-%(current)li ფაილის ჩამოქაჩვა %(total)li-დან. სიჩქარე - %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "მე-%(current)li ფაილის ჩამოქაჩვა %(total)li-დან" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "ცნობები" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "ცვლილებების სია არ არის ხელმისაწვდომი." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"ვერ განხორციელდა ცვლილებების სიის ჩამოქაჩვა.\n" +"შეამოწმეთ ინტერნეტ-კავშირი." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "'%s' ვერ დაყენდა" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "ამით საჭირო პაკეტი წაიშლება" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/ko.po b/po/ko.po new file mode 100644 index 0000000..46d2613 --- /dev/null +++ b/po/ko.po @@ -0,0 +1,659 @@ +# Korean translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# darehanl , 2006. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:04+0000\n" +"Last-Translator: Eungkyu Song \n" +"Language-Team: Korean \n" +"Language: ko\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "우분투 5.04 보안 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "우분투 5.10 'Breezy Badger' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "우분투 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "우분투 4.10 'Warty Warthog' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "우분투 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "우분투 4.10 'Warty Warthog' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "우분투 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "우분투 4.10 'Warty Warthog' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "우분투 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "우분투 5.04 'Hoary Hedgehog' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "우분투 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "우분투 4.10 'Warty Warthog' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "우분투 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "우분투 4.10 'Warty Warthog' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "우분투 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "우분투 5.04 'Hoary Hedgehog' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "우분투 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "우분투 5.04 'Hoary Hedgehog' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "우분투 5.04 보안 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "우분투 5.10 'Breezy Badger' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "우분투 5.04 보안 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "우분투 5.10 'Breezy Badger' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "우분투 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "커뮤니티에서 관리" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "제한된 소프트웨어" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "우분투 6.10 'Edgy Eft' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "우분투 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Canonical이 지원하는 오픈 소스 소프트웨어" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "커뮤니티에서 관리 (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "커뮤니티에서 관리하는 오픈 소스 소프트웨어" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "비자유 드라이버" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "장치의 독점 드라이버" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "제한된 소프트웨어 (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "우분투 6.06 LTS 'Dapper Drake' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "중요한 보안 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "추천하는 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "제안하는 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Backport 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "우분투 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "우분투 5.10 'Breezy Badger' 씨디롬" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "우분투 5.10 보안 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "우분투 5.10 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "우분투 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "우분투 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "우분투 5.04 'Hoary Hedgehog' 씨디롬" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "공식적으로 지원함" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "우분투 5.04 보안 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "우분투 5.04 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "우분투 5.04 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "우분투 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "커뮤니티에서 관리 (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "비자유 (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "우분투 4.10 'Warty Warthog' 씨디롬" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "더 이상 공식적으로 지원하지 않음" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "저작권이 제한됨" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "우분투 4.10 보안 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "우분투 4.10 업데이트" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "우분투 4.10 Backports" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "데비안 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "데비안 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "데비안 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "데비안 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "데비안 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "제안하는 업데이트" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "중요한 보안 업데이트" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "데비안 \"Etch\" (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "데비안 \"Sid\" (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG 호환이 되지만 비자유 소프트웨어에 의존하는 소프트웨어" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "DFSG와 호환이 되지 않는 소프트웨어" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "%s 서버" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "주 서버" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "사용자 정의 서버" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" +"%(total)li개중 %(current)li번째 파일을 %(speed)s/s의 속도로 받고 있습니다" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "%(total)li개중 %(current)li번째 파일을 받고 있습니다" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "자세한 정보" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "변경 사항 목록이 없습니다" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"변경 사항 목록을 다운로드하는데 실패했습니다. 인터넷 연결을 확인해 주십시오." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "'%s'을(를) 설치할 수 없습니다" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "필수적인 패키지를 제거해야만 합니다." + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/ku.po b/po/ku.po new file mode 100644 index 0000000..9ba4a54 --- /dev/null +++ b/po/ku.po @@ -0,0 +1,660 @@ +# Kurdish translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-17 09:50+0000\n" +"Last-Translator: rizoye-xerzi \n" +"Language-Team: Kurdish \n" +"Language: ku\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Rojanekirinên Ewlekariyên yên Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Cdroma Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Cdroma Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Cdroma Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Cdroma Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Cdroma Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Cdroma Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Cdroma Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Cdroma Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Cdroma Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Rojanekirinên Ewlekariyên yên Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Cdroma Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Rojanekirinên Ewlekariyên yên Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Cdroma Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Yên ji aliyê komekê ber çav hatiye derbaskirin" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Nivîsbariya bi sînor" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Cdroma Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Çavkaniya xwezayî ya li gorî bingeha nermalavê" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Yên ji aliyê koman lê hatine nihêrtin" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "" +"Nivîsbariyên Kodên Çavkaniyên Azad yên ji aliyê koman lê hatine nihêrtin" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Ajokerên ne azad" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Ji bo cîhazan ajokerên ku çavkaniyên wan girtî ne" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Nivîsbariya bi sînor" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Nivîsbariya bi mafên weşan û belavkirinê sînor kirî" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Cdroma Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Rojanekirinên ewlekariyê yên girîng" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Rojanekirinên têne pêşniyarkirin" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Rojanekirinên hatine pêşniyarkirin" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Rojanekirinên paş de hatine kişandin" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Cdroma Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Rojanekirinên Ewlekariyê yên Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Rojanekirina Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Rojanekirinên Paş de Hatine Kişandin yên Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Cdroma Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Bi piştgiriya fermî" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Rojanekirinên Ewlekariyên yên Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Rojanekirinên Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Rojanekirinên Paş de Hatine Kişandin yên Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Yên ji aliyê koman ve lê tê nihêrîn (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Ne-azad (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Cdroma Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Êdi bi awayekî fermî nayê destekkirin" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Mafê kopîkrinê yê sînorkirî" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Rojanekirinên Ubuntu 4.10 yên Ewlekarî" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Rojanekirinên Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 nivîsbariyên bi paş de kişandî (Backports)" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Rojanekirinên hatine pêşniyarkirin" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Rojanekirinên ewlekariyê yên girîng" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-nivîsbariya hevgirtî ya ne azad" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "nivîsbariya hevgirtî ya ne li gorî -DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Pêşkêşkera %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Pêşkêşkera Mak" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Pêşkêşkera taybet" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Pelgeha %(current)li ji %(total)li bi %(speed)s/ç tê daxistin" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Pelgeha %(current)li ji %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Hûragahî" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Lîsteya guherînan ne gihiştbar e" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Daxistina lîsteya guhertinan biserneket.\n" +"Ji kerema xwe re girêdana internetê kontrol bike." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Nikarî '%s' saz bike" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Dê pêwiste be ku pakêta bingehîn were jêbirin" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/lt.po b/po/lt.po new file mode 100644 index 0000000..7fd8f1f --- /dev/null +++ b/po/lt.po @@ -0,0 +1,664 @@ +# Lithuanian translation for Update Manager package. +# Copyright (C) 2005, the Free Software Foundation, Inc. +# This file is distributed under the same license as the update-manager package. +# Žygimantas Beručka , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager HEAD\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:04+0000\n" +"Last-Translator: Mantas Kriaučiūnas \n" +"Language-Team: Lithuanian \n" +"Language: lt\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n" +"%100<10 || n%100>=20) ? 1 : 2);\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.04 saugumo atnaujinimai" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD diskas su Ubuntu 5.10 „Breezy Badger“" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD diskas su Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD diskas su Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD diskas su Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD diskas Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD diskas su Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 „Warty Warthog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD diskas su Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD diskas Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD diskas Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.04 saugumo atnaujinimai" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD diskas su Ubuntu 5.10 „Breezy Badger“" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.04 saugumo atnaujinimai" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD diskas su Ubuntu 5.10 „Breezy Badger“" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Prižiūrima bendruomenės" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +#, fuzzy +msgid "Restricted software" +msgstr "Ne Laisva (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD diskas su Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +#, fuzzy +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS „Dapper Drake“" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Prižiūrima bendruomenės (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Prižiūrima bendruomenės (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Bendruomenės prižiūrima laisva programinė įranga" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +#, fuzzy +msgid "Non-free drivers" +msgstr "Ne Laisva (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +#, fuzzy +msgid "Restricted software (Multiverse)" +msgstr "Ne Laisva (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CD diskas su Ubuntu 6.06 LTS „Dapper Drake“" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Svarbūs saugumo atnaujinimai" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Rekomenduojami atnaujinimai" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Testuojami atnaujinimai" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Naujos ir atnaujintos programos" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 „Breezy Badger“" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD diskas su Ubuntu 5.10 „Breezy Badger“" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 saugumo atnaujinimai" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 atnaujinimai" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Naujos programos Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD diskas Ubuntu 5.04 „Hoary Hedgehog“" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Oficialiai palaikoma" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 saugumo atnaujinimai" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 atnaujinimai" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Naujos programos Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 „Warty Warthog“" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Prižiūrima bendruomenės (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Ne Laisva (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD diskas su Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +#, fuzzy +msgid "No longer officially supported" +msgstr "Kai kuri programinė įranga nebėra oficialiai palaikoma" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Apribotos autorinės teisės" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 saugumo atnaujinimai" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 atnaujinimai" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Naujos programos Ubuntu 4.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 „Sarge“" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 „Sarge“" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 „Sarge“" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 „Sarge“" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 „Sarge“" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Testuojami atnaujinimai" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Svarbūs saugumo atnaujinimai" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian „Etch“ (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian „Sid“ (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Su DFSG suderinama programinė įranga su Ne Laisvomis priklausomybėmis" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Su DFSG nesuderinama programinė įranga" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Atsiunčiamas failas %(current)li iš %(total)li, %(speed)s/s greičiu" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Atsiunčiamas failas %(current)li iš %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detalės" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Pakeitimų sąrašas neprieinamas" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Nepavyko atsiųsti pakeitimų sąrašo. \n" +"Patikrinkite Interneto ryšį." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Negalima įdiegti „%s“" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Turėtų būti pašalintas esminis paketas" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/lv.po b/po/lv.po new file mode 100644 index 0000000..272b8c9 --- /dev/null +++ b/po/lv.po @@ -0,0 +1,627 @@ +# translation of lp-upd-manager-lv.po to Latvian +# Latvian translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# +# FIRST AUTHOR , 2006. +# Raivis Dejus , 2006. +msgid "" +msgstr "" +"Project-Id-Version: lp-upd-manager-lv\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-09-05 20:00+0000\n" +"Last-Translator: Raivis Dejus \n" +"Language-Team: Latvian \n" +"Language: lv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : " +"2);\n" +"X-Generator: KBabel 1.11.2\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Sabiedrības uzturētie (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Sabiedrības uzturētie (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Sabiedrības uzturētie (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Sabiedrības uzturētie (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "%s atjauninājumi" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Oficiāli atbalstītie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Sabiedrības uzturētie (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Maksas (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Saistītie autortiesību" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "%s atjauninājumi" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Galvenais serveris" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detaļas" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Nevar instalēt '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/mk.po b/po/mk.po new file mode 100644 index 0000000..bb6f0c9 --- /dev/null +++ b/po/mk.po @@ -0,0 +1,681 @@ +# translation of mk.po to Macedonian +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) 2005 THE PACKAGE'S COPYRIGHT HOLDER. +# Арангел Ангов , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: mk\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:04+0000\n" +"Last-Translator: Арангел Ангов \n" +"Language-Team: Macedonian \n" +"Language: mk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural= n==1 || n%10==1 ? 0 : 1\n" +"X-Generator: KBabel 1.10\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Безбедносни надградби за Убунту 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD диск со Убунту 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD диск со Убунту 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD диск со Убунту 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD диск со Убунту 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD диск со Убунту 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "CD диск со Убунту 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD диск со Убунту 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Безбедносни надградби за Убунту 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD диск со Убунту 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Безбедносни надградби за Убунту 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD диск со Убунту 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +#, fuzzy +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Надградби за Убунту 5.10" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Оддржувано од заедницата (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +#, fuzzy +msgid "Restricted software" +msgstr "Додатен софтвер" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +#, fuzzy +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +#, fuzzy +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Надградби за Убунту 5.04" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Оддржувано од заедницата (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Оддржувано од заедницата (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Оддржувано од заедницата (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +#, fuzzy +msgid "Non-free drivers" +msgstr "Неслободно (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +#, fuzzy +msgid "Restricted software (Multiverse)" +msgstr "Неслободно (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +#, fuzzy +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Надградби за Убунту 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +#, fuzzy +msgid "Important security updates" +msgstr "Безбедносни надградби за Debian Stable" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Инсталирам надградби..." + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Инсталирам надградби..." + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +#, fuzzy +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "CD диск со Убунту 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +#, fuzzy +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD диск со Убунту 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Безбедносни надградби за Убунту 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Надградби за Убунту 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +#, fuzzy +msgid "Ubuntu 5.10 Backports" +msgstr "Надградби за Убунту 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +#, fuzzy +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD диск со Убунту 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +#, fuzzy +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD диск со Убунту 5.04 \"Hoary Hedgehog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Официјално поддржано" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Безбедносни надградби за Убунту 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Надградби за Убунту 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +#, fuzzy +msgid "Ubuntu 5.04 Backports" +msgstr "Надградби за Убунту 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +#, fuzzy +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Оддржувано од заедницата (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Неслободно (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +#, fuzzy +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD диск со Убунту 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +#, fuzzy +msgid "No longer officially supported" +msgstr "Официјално поддржано" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Restricted copyright" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Безбедносни надградби за Убунту 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Надградби за Убунту 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +#, fuzzy +msgid "Ubuntu 4.10 Backports" +msgstr "Надградби за Убунту 5.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +#, fuzzy +msgid "Proposed updates" +msgstr "Инсталирам надградби..." + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Безбедносни надградби за Debian Stable" + +#. Description +#: ../data/templates/Debian.info.in:133 +#, fuzzy +msgid "Debian current stable release" +msgstr "Debian Unstable \"Sid\"" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian Testing" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian Non-US (Unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-компатибилен софтвер со неслободни зависности" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Не-DFSG-компатибилен софтвер" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +#, fuzzy +msgid "Details" +msgstr "Детали" + +#: ../apt/progress/gtk2.py:428 +#, fuzzy +msgid "Starting..." +msgstr "Поставувања" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +#, fuzzy +msgid "The list of changes is not available" +msgstr "Достапна е нова верзија на Убунту!" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Не успеав да ги преземам промените. Ве молам проверете дали Вашата интернет " +"врска е активна." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Не може да се инсталира %s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Важен пакет мора да се отстрани" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/nb.po b/po/nb.po new file mode 100644 index 0000000..58e1b56 --- /dev/null +++ b/po/nb.po @@ -0,0 +1,683 @@ +# translation of nb.po to Norwegian Bokmal +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Terance Edward Sola , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: nb\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:04+0000\n" +"Last-Translator: Hans Petter Birkeland \n" +"Language-Team: Norwegian Bokmal \n" +"Language: nb\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" +"X-Generator: KBabel 1.10\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.10 Sikkerhetsoppdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD med Ubuntu 5.04 «Hoary Hedgedog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD med Ubuntu 5.04 «Hoary Hedgedog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD med Ubuntu 5.04 «Hoary Hedgedog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD med Ubuntu 5.04 «Hoary Hedgedog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "CD med Ubuntu 5.04 «Hoary Hedgedog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD med Ubuntu 5.04 «Hoary Hedgedog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.10 Sikkerhetsoppdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.10 Sikkerhetsoppdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +#, fuzzy +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 5.10 Oppdateringer" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Vedlikeholdt av miljøet (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +#, fuzzy +msgid "Restricted software" +msgstr "Bidratt programvare" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +#, fuzzy +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +#, fuzzy +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Vedlikeholdt av miljøet (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Vedlikeholdt av miljøet (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Vedlikeholdt av miljøet (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +#, fuzzy +msgid "Non-free drivers" +msgstr "Non-free (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +#, fuzzy +msgid "Restricted software (Multiverse)" +msgstr "Non-free (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +#, fuzzy +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +#, fuzzy +msgid "Important security updates" +msgstr "Ubuntu 5.10 Sikkerhetsoppdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +#, fuzzy +msgid "Recommended updates" +msgstr "Anbefalte oppdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Installerer oppdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Installerer oppdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +#, fuzzy +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 Sikkerhetsoppdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 Oppdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +#, fuzzy +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD med Ubuntu 5.04 «Hoary Hedgedog»" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +#, fuzzy +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD med Ubuntu 5.04 «Hoary Hedgedog»" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Offisielt støttet" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +#, fuzzy +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.10 Sikkerhetsoppdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +#, fuzzy +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.10 Oppdateringer" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +#, fuzzy +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +#, fuzzy +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Vedlikeholdt av miljøet (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Non-free (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +#, fuzzy +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD med Ubuntu 4.10 «Warty Warthog»" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +#, fuzzy +msgid "No longer officially supported" +msgstr "Noe programvare er ikke lenger offisielt støttet" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Begrenset opphavsrett" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +#, fuzzy +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 5.10 Backports" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian Testing" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian Testing" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +#, fuzzy +msgid "Proposed updates" +msgstr "Installerer oppdateringer" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Ubuntu 5.10 Sikkerhetsoppdateringer" + +#. Description +#: ../data/templates/Debian.info.in:133 +#, fuzzy +msgid "Debian current stable release" +msgstr "Debian Unstable «Sid»" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-kompatiblel programvare med Non-Free avhengigheter" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Ikke-DFSG-kompatibel programvare" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, fuzzy, python-format +msgid "Server for %s" +msgstr "Tjener for %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +#, fuzzy +msgid "Main server" +msgstr "Hovedtjener" + +#: ../aptsources/distro.py:250 +#, fuzzy +msgid "Custom servers" +msgstr "Egendefinerte tjenere" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Laster ned filen %li av %li med %s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Laster ned filen %li av %li med %s/s" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detaljer" + +#: ../apt/progress/gtk2.py:428 +#, fuzzy +msgid "Starting..." +msgstr "Instillinger" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +#, fuzzy +msgid "The list of changes is not available" +msgstr "Listen over endringer er ikke tilgjengelig ennå. Prøv senere." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Kunne ikke laste ned listen med endringer. Vennligst kontrollér " +"internettilkoblingen." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Kan ikke installere '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "En nødvendig pakke må fjernes" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/ne.po b/po/ne.po new file mode 100644 index 0000000..e7de8d8 --- /dev/null +++ b/po/ne.po @@ -0,0 +1,682 @@ +# translation of update-manager.HEAD.po to Nepali +# This file is distributed under the same license as the PACKAGE package. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER. +# Pawan Chitrakar , 2005. +# Jaydeep Bhusal , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager.HEAD\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:13+0000\n" +"Last-Translator: Jaydeep Bhusal \n" +"Language-Team: Nepali \n" +"Language: ne\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: KBabel 1.9.1\n" +"Plural-Forms: nplurals=2;plural=(n!=0)\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +#, fuzzy +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "युबन्टु ५.०४ अद्यावधिकहरु" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "समुदाय सम्हालिएको (ब्रह्माण्ड)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +#, fuzzy +msgid "Restricted software" +msgstr "योगदान गरिएको सफ्टवेयर" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +#, fuzzy +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "युबन्टु ५.०४ अद्यावधिकहरु" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "समुदाय सम्हालिएको (ब्रह्माण्ड)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "समुदाय सम्हालिएको (ब्रह्माण्ड)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "समुदाय सम्हालिएको (ब्रह्माण्ड)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +#, fuzzy +msgid "Non-free drivers" +msgstr "नन-फ्री (बहुभर्स)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +#, fuzzy +msgid "Restricted software (Multiverse)" +msgstr "नन-फ्री (बहुभर्स)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +#, fuzzy +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "युबन्टु ५.०४ अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +#, fuzzy +msgid "Important security updates" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "स्तरवृद्धिहरु स्थापना गर्दै" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "स्तरवृद्धिहरु स्थापना गर्दै" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +#, fuzzy +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +#, fuzzy +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +#, fuzzy +msgid "Ubuntu 5.10 Security Updates" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +#, fuzzy +msgid "Ubuntu 5.10 Updates" +msgstr "युबन्टु ५.०४ अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +#, fuzzy +msgid "Ubuntu 5.10 Backports" +msgstr "युबन्टु ५.०४ अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +#, fuzzy +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +#, fuzzy +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +#, fuzzy +msgid "Officially supported" +msgstr "कार्यालय बाट समर्थित" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +#, fuzzy +msgid "Ubuntu 5.04 Security Updates" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +#, fuzzy +msgid "Ubuntu 5.04 Updates" +msgstr "युबन्टु ५.०४ अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +#, fuzzy +msgid "Ubuntu 5.04 Backports" +msgstr "युबन्टु ५.०४ अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +#, fuzzy +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "समुदाय सम्हालिएको (ब्रह्माण्ड)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "नन-फ्री (बहुभर्स)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +#, fuzzy +msgid "No longer officially supported" +msgstr "कार्यालय बाट समर्थित" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "निषेधित प्रतिलिपि अधिकार" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "युबन्टु ४.१० सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +#, fuzzy +msgid "Ubuntu 4.10 Updates" +msgstr "युबन्टु ५.०४ अद्यावधिकहरु" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +#, fuzzy +msgid "Ubuntu 4.10 Backports" +msgstr "युबन्टु ५.०४ अद्यावधिकहरु" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "डेबियन अचल सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "डेबियन अचल सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "डेबियन अचल सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "डेबियन अचल सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "डेबियन अचल सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Debian.info.in:119 +#, fuzzy +msgid "Proposed updates" +msgstr "स्तरवृद्धिहरु स्थापना गर्दै" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "युबन्टु ५.०४ सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Debian.info.in:133 +#, fuzzy +msgid "Debian current stable release" +msgstr "डेबियन अचल सुरक्षा अद्यावधिकहरु" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "डेबियन अचल सुरक्षा अद्यावधिकहरु" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +#, fuzzy +msgid "Details" +msgstr "विवरणहरु" + +#: ../apt/progress/gtk2.py:428 +#, fuzzy +msgid "Starting..." +msgstr "सेटिंगहरु" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +#, fuzzy +msgid "The list of changes is not available" +msgstr "युबन्टुको एउटा नयाँ विमोचन उपलब्ध छ!" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "परिवर्तनहरु डाउनलोड गर्न असफल. यदि सक्रिय इन्टरनेट जडान छ भने जाँच्नुहोस" + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/nl.po b/po/nl.po new file mode 100644 index 0000000..24f3e26 --- /dev/null +++ b/po/nl.po @@ -0,0 +1,639 @@ +# Ducht translation of python-apt. +# Copyright (C) 2006-2012 THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the python-apt package. +# Tino Meinen , 2006. +# Jeroen Schot \n" +"Language-Team: Debian l10n Dutch \n" +"Language: nl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD met Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD met Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD met Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD met Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Partners van Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Software dis is verpakt door Canonical voor zijn partners" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Deze software is geen onderdeel van Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Onafhankelijk" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Aangeboden door externe ontwikkelaars" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Software die door externe ontwikkelaars wordt aangeboden." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD met Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD met Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD met Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD met Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD met Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD met Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD met Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Door de gemeenschap beheerd" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Beperkte software" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD met Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Door Canonical ondersteunde vrije en opensourcesoftware" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Door de gemeenschap beheerd (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Door de gemeenschap beheerde vrije en opensourcesoftware" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Niet-vrije stuurprogramma's" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Niet-vrije stuurprogramma's voor apparaten" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Beperkte software (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" +"Software die door auteursrechten of wettelijke regelingen beperkt wordt." + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CD met Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Belangrijke veiligheidsupdates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Aanbevolen updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Voorgestelde updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Niet-ondersteunde updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD met Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 veiligheidsupdates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD met Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Officieel ondersteund" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 veiligheidsupdates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Door de gemeenschap beheerd (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Niet-vrij (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD met Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Niet meer officieel ondersteund" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Beperkte auteursrechten" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 veiligheidsupdates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 backports" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 'Wheezy' " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 'Squeeze' " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 'Lenny' " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 'Etch'" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 'Sarge'" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Voorgestelde updates" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "veiligheidsupdates" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Huidige stabiele uitgave van Debian" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian testing (test)" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian 'Sid' (unstable/onstabiel)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Software compatibel met DFSG, maar met niet-vrije afhankelijkheden" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Software niet compatibel met DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Server voor %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Hoofdserver" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Andere servers" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Downloaden van bestand %(current)li uit %(total)li met %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Downloaden van bestand %(current)li uit %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Details" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Opstarten..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Voltooid" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" +"Ongeldige unicode in de beschrijving van '%s' (%s). Gelieve dit te melden." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Een overzicht van de wijzigingen is nog niet beschikbaar." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"De lijst van veranderingen is nog niet beschikbaar\n" +"\n" +"Gebruik http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"todat de veranderingen beschikbaar zijn of probeer het later nog eens." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Kon de lijst met wijzigingen niet downloaden. \n" +"Controleer uw internetverbinding." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "De lijst van bestanden voor '%s' kon niet gelezen worden" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "De lijst van bestanden voor '%s' kon niet gelezen worden" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Afhankelijkheid is niet vervulbaar: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Conflicteerd met het geinstalleerde pakket '%s'" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Maakt het bestaande pakket '%(pkgname)s' stuk door afhankelijkheid " +"%(depname)s (%(deprelation)s %(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Maakt het bestaande pakket '%(pkgname)s' stuk door conflict: %(targetpkg)s " +"(%(comptype)s %(targetver)s) " + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Maakt het bestaande pakket '%(pkgname)s' stuk die conflicteert: " +"'%(targetpkg)s'. Maar de '%(debfile)s biedt deze aan via: '%(provides)s'" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Pakket heeft geen Architecture-veld" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Verkeerde architectuur '%s'" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Er is al een nieuwere versie geïnstalleerd" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Voldoen van alle vereisten is mislukt (defecte cache)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "Kan '%s' niet installeren" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Automatisch uitgepakt:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Automatisch omgezet naar toonbare ASCII:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"Installeer de bouwevereisten voor het bronpakket '%s' waaruit '%s' wordt " +"gebouwd\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Een essentieel pakket zou verwijderd worden" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Klaar" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Geraakt " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Genegeerd " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Fout " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Ophalen:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [Bezig]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Medium wisselen: Gelieve de schijf met label\n" +" '%s'\n" +"in het station '%s' te plaatsen en op 'enter' te drukken\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "%sB opgehaald in %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" +"Gelieve een naam voor deze schijf op te geven, bijvoorbeeld 'Debian 2.1r1 " +"schijf 1'" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Gelieve een schijf in het station te plaatsen en op 'Enter' te drukken" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Opbouwen van pakketstructuren" diff --git a/po/oc.po b/po/oc.po new file mode 100644 index 0000000..4b4647c --- /dev/null +++ b/po/oc.po @@ -0,0 +1,661 @@ +# Occitan (post 1500) translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-18 10:01+0000\n" +"Last-Translator: Yannig MARCHEGAY (Kokoyaya) \n" +"Language-Team: Occitan (post 1500) \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Mesas a jorn de seguretat per Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD-ROM amb Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD-ROM que conten Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD-ROM que conten Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD-ROM que conten Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD-ROM que conten Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD-ROM que conten Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD-ROM que conten Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD-ROM que conten Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD-ROM que conten Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Mesas a jorn de seguretat per Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD-ROM amb Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Mesas a jorn de seguretat per Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD-ROM amb Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +#, fuzzy +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +#, fuzzy +msgid "Restricted software" +msgstr "Pas liure (multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD-ROM que conten Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +#, fuzzy +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Mesas a jorn per Ubuntu 6.06 LTS" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Pilòts pas liures" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +#, fuzzy +msgid "Restricted software (Multiverse)" +msgstr "Pas liure (multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CD-ROM que conten Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Mesas a jorn de seguretat importantas" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Autras mesas a jorn" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Mesas a jorn de seguretat importantas" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD-ROM amb Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Mesas a jorn de seguretat per Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +#, fuzzy +msgid "Ubuntu 5.10 Updates" +msgstr "Mesas a jorn per Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +#, fuzzy +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD-ROM que conten Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Mesas a jorn de seguretat per Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +#, fuzzy +msgid "Ubuntu 5.04 Updates" +msgstr "Mesas a jorn per Ubuntu 6.06 LTS" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +#, fuzzy +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Pas liure (multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +#, fuzzy +msgid "Ubuntu 4.10 Security Updates" +msgstr "Mesas a jorn per Ubuntu 6.06 LTS" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +#, fuzzy +msgid "Ubuntu 4.10 Updates" +msgstr "Mesas a jorn per Ubuntu 6.06 LTS" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Mesas a jorn de seguretat importantas" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (en tèst)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (instable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Servidor per %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Servidor principal" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Servidors personalizats" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detalhs" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "La tièra de las modificacioons es pas disponibla" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "Verificatz vòstra connection internet." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Impossible d'installar '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/pl.po b/po/pl.po new file mode 100644 index 0000000..d6c4c48 --- /dev/null +++ b/po/pl.po @@ -0,0 +1,644 @@ +# Polish translation of Update Manager. +# Copyright (C) 2005 Zygmunt Krynicki +# This file is distributed under the same license as the update-manager package. +# +# Dominik Zablotny , 2006. +# Michał Kułach , 2012. +msgid "" +msgstr "" +"Project-Id-Version: update-manager cvs\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2012-07-28 23:07+0100\n" +"Last-Translator: Michał Kułach \n" +"Language-Team: Polish \n" +"Language: pl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 " +"|| n%100>=20) ? 1 : 2);\n" +"X-Generator: Lokalize 1.4\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 \"Precise Pangolin\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD-ROM z Ubuntu 12.04 \"Precise Pangolin\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 \"Oneiric Ocelot\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD-ROM z Ubuntu 11.10 \"Oneiric Ocelot\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 \"Natty Narwhal\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD-ROM z Ubuntu 11.04 \"Natty Narwhal\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 \"Maverick Meerkat\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD-ROM z Ubuntu 10.10 \"Maverick Meerkat\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Partnerzy Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Programy spakietowane przez firmę Canonical dla jej partnerów" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "To oprogramowanie nie jest częścią Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Niezależne" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Udostępniane przez zewnętrznych deweloperów" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Oprogramowanie oferowane przez zewnętrznych deweloperów." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 \"Lucid Lynx\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD-ROM z Ubuntu 10.04 \"Lucid Lynx\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 \"Karmic Koala\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD-ROM z Ubuntu 9.10 \"Karmic Koala\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 \"Jaunty Jackalope\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD-ROM z Ubuntu 9.04 \"Jaunty Jackalope\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 \"Intrepid Ibex\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD-ROM z Ubuntu 8.10 \"Intrepid Ibex\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 \"Hardy Heron\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD-ROM z Ubuntu 8.04 \"Hardy Heron\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 \"Gutsy Gibbon\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD-ROM z Ubuntu 7.10 \"Gutsy Gibbon\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 \"Feisty Fawn\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD-ROM z Ubuntu 7.04 \"Feisty Fawn\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 \"Edgy Eft\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Pod opieką społeczności" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Ograniczone oprogramowanie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD-ROM z Ubuntu 6.10 \"Edgy Eft\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS \"Dapper Drake\"" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Wolne i otwarte oprogramowanie wspierane przez firmę Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Utrzymywane przez społeczność (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Wolne i otwarte oprogramowanie wspierane przez społeczność" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Sterowniki niewolne" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Własnościowe sterowniki do urządzeń" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Oprogramowanie niewolnodostępne (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" +"Oprogramowanie ograniczone prawami autorskimi lub problemami natury prawnej" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CD-ROM z Ubuntu 6.06 LTS \"Dapper Drake\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Ważne aktualizacje bezpieczeństwa" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Aktualizacje polecane" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Wstępne wydania aktualizacji" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Niewspierane aktualizacje" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD-ROM z Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Aktualizacje bezpieczeństwa do Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Aktualizacje do Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Aktualizacje do Ubuntu 5.10 (backporty)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu·5.04·\"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD-ROM z Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Wspierane oficjalnie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Aktualizacje bezpieczeństwa do Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Aktualizacje do Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Aktualizacje do Ubuntu 5.04 (backporty)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu·4.10·\"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Utrzymywane przez społeczność (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Niewolne (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD-ROM z Ubuntu 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Już nieobsługiwane" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "O ograniczonych prawach kopiowania" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Aktualizacje bezpieczeństwa do Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Aktualizacje do Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Aktualizacje do Ubuntu 4.10 (backporty)" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 \"Wheezy\" " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 \"Squeeze\" " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 \"Lenny\" " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 \"Etch\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Aktualizacje proponowane" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Aktualizacje bezpieczeństwa" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Obecne wydanie stabilne Debiana" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Dystrybucja testowa Debiana" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (niestabilny)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Oprogramowanie kompatybilne z DFSG z niewolnymi zależnościami" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Oprogramowanie niekompatybilne z DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Serwer dla kraju %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Serwer główny" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Inne serwery" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Pobieranie pliku %(current)li z %(total)li z prędkością %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Pobieranie pliku %(current)li z %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Szczegóły" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Rozpoczynanie..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Zakończono" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" +"Nieprawidłowy znak unikodu w opisie pakietu \"%s\" (%s). Prosimy zgłosić ten " +"błąd." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Lista zmian nie jest dostępna" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"Lista zmian nie jest jeszcze dostępna.\n" +"\n" +"Proszę użyć http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"dopóki zmiany nie będą dostępne lub spróbować ponownie później." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Nie udało się pobrać listy zmian. \n" +"Proszę sprawdzić swoje połączenie internetowe." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Nie można odczytać listy plików \"%s\"" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Nie można odczytać listy plików kontrolnych \"%s\"" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Zależność nie może być spełniona: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Konflikty z zainstalowanym pakietem \"%s\"" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Psuje istniejący pakiet \"%(pkgname)s\" zależność %(depname)s " +"(%(deprelation)s %(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Psuje istniejący pakiet \"%(pkgname)s\" konflikt: %(targetpkg)s " +"(%(comptype)s %(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Psuje istniejący pakiet \"%(pkgname)s\", następującym konfliktem: " +"\"%(targetpkg)s\". Jest on udostępniany przez \"%(debfile)s\" za pomocą: " +"\"%(provides)s\"" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Brak pola architektury (Architecture) w pakiecie" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Nieprawidłowa architektura \"%s\"" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Nowsza wersja jest już zainstalowana" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Nie udało się spełnić wszystkich zależności (zepsuta pamięć podręczna)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "Nie można zainstalować \"%s\"" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Automatycznie rozpakowano:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Automatycznie skonwertowano do drukowalnego ascii:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"Instalacja zależności czasu budowania pakietu źródłowego \"%s\", który " +"buduje %s\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Istotny pakiet musiałby zostać usunięty" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Gotowe" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Stary " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Ign. " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Błąd " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Pobieranie:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [Pracuje]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Zmiana nośnika: proszę włożyć płytę oznaczoną\n" +" \"%s\"\n" +"do napędu \"%s\" i wcisnąć enter\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Pobrano %sB w %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "Proszę wprowadzić nazwę dla tej płyty, np. \"Debian 2.1r1 Disk 1\"" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Proszę włożyć dysk do napędu i nacisnąć enter" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Budowanie struktur danych" diff --git a/po/pt.po b/po/pt.po new file mode 100644 index 0000000..aca824f --- /dev/null +++ b/po/pt.po @@ -0,0 +1,657 @@ +# Portuguese translation of update-manager. +# Copyright (C) 2005 Free Software Foundation, Inc. +# This file is distributed under the same license as the update-manager package. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 11:04+0000\n" +"Last-Translator: Tiago Silva \n" +"Language-Team: Ubuntu Portuguese Team \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Actualizações de Segurança do Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Cdrom com o Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Cdrom com Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Cdrom com Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Cdrom com Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Cdrom com o Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Cdrom com Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Cdrom com Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Cdrom com o Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Cdrom com o Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Actualizações de Segurança do Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Cdrom com o Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Actualizações de Segurança do Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Cdrom com o Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Mantido pela comunidade" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Software Restrito" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Cdrom com o Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Software de Código Aberto suportado pela Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Mantido pela comunidade (universal)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Software de Código Fonte Aberto mantido pela comunidade" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Controladores não-livres" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Drivers proprietários para dispositivos" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Software não-livre (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Software restringido por copyright ou questões legais" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Cdrom com o Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Actualizações de segurança importantes" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Actualizações recomendadas" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Actualizações propostas" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Actualizações dos repositórios \"backport\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Cdrom com o Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 Actualizações de Segurança" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 Actualizações" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Cdrom com o Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Suportado Oficialmente" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Actualizações de Segurança do Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Actualizações do Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Backports do Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Mantido pela comunidade (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Não-livre (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Cdrom com Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Sem mais suporte oficial" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Direitos de autor restritos" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Actualizações de Segurança do Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Actualizações do Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Backports do Ubuntu 4.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Actualizações propostas" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Actualizações de segurança importantes" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Software compatível-DFSG com Dependências Não-Livres" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Software compatível-DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Servidor para %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Servidor principal" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Servidores personalizados" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "A descarregar ficheiro %(current)li de %(total)li a %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "A descarregar ficheiro %(current)li de %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detalhes" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "A lista de alterações não está disponível." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Falha ao descarregar a lista de alterações. \n" +"Por favor verifique a sua ligação à Internet." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Impossível de instalar '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Um pacote essencial teria que ser removido" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/pt_BR.po b/po/pt_BR.po new file mode 100644 index 0000000..fe0d5ce --- /dev/null +++ b/po/pt_BR.po @@ -0,0 +1,648 @@ +# Brazilian Portuguese translation for python-apt. +# This file is distributed under the same licence as the update-manager package. +# Sérgio Cipolla , 2010 - 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2012-06-10 15:53-0300\n" +"Last-Translator: Sérgio Cipolla \n" +"Language-Team: \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Poedit-Language: Portuguese\n" +"X-Poedit-Country: BRAZIL\n" +"Plural-Forms: nplurals=2; plural=n > 1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD-ROM com o Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD-ROM com o Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD-ROM com o Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD-ROM com o Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Parceiros da Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Aplicativos empacotados pela Canonical para os seus parceiros" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Estes aplicativos não são parte do Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Independentes" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Fornecidos por desenvolvedores de software terceiros" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Aplicativos oferecidos por desenvolvedores terceiros." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD-ROM com o Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD-ROM com o Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD-ROM com o Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "CD-ROM com o Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD-ROM com o Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD-ROM com o Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD-ROM com o Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Mantido pela comunidade" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Aplicativos restritos" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD-ROM com o Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Aplicativos livres de código aberto suportados pela Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Mantido pela comunidade (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Aplicativos livres de código aberto mantidos pela comunidade" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Drivers não-livres" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Drivers proprietários para dispositivos" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Aplicativos restritos (multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Aplicativos restritos por copyright ou questões legais" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CD-ROM com o Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Atualizações de segurança importantes" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Atualizações recomendadas" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Atualizações de pré-lançamento" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Atualizações não suportadas" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD-ROM com o Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Atualizações de segurança do Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Atualizações do Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Backports do Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD-ROM com o Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Suportados oficialmente" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Atualizações de segurança do Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Atualizações do Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Backports do Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Mantido pela comunidade (universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Não-livres (multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD-ROM com o Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Não mais suportado oficialmente" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Copyright restrito" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Atualizações de segurança do Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Atualizações do Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Backports do Ubuntu 4.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 'Wheezy' " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 'Squeeze' " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 'Lenny' " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 'Etch'" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 'Sarge'" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Atualizações sugeridas" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Atualizações de segurança" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Atual versão estável do Debian" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian testing" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian 'Sid' (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Aplicativos compatíveis com a DFSG mas com dependências não-livres" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Aplicativos não compatíveis com a DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Servidor - %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Servidor principal" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Servidores personalizados" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Baixando arquivo %(current)li de %(total)li a %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Baixando arquivo %(current)li de %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detalhes" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Iniciando..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Completo" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "Unicode inválido na descrição de '%s' (%s). Por favor, relate o erro." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "A lista de alterações não está disponível" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"A lista de alterações ainda não está disponível.\n" +"\n" +"Por favor, utilize http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"até que as alterações estejam disponíveis ou tente novamente mais tarde." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Falha ao baixar a lista de alterações. \n" +"Por favor verifique sua conexão com a Internet." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "A lista de arquivos de '%s' não pôde ser lida" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "A lista de arquivos de controle de '%s' não pôde ser lida" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "A dependência não é contentável: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Conflita com o pacote instalado '%s'" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Quebra o pacote existente '%(pkgname)s', dependência %(depname)s " +"(%(deprelation)s %(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Quebra o pacote existente '%(pkgname)s', conflito: %(targetpkg)s " +"(%(comptype)s %(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Quebra o pacote existente '%(pkgname)s' que conflita com '%(targetpkg)s'. " +"Mas '%(debfile)s' o provê via '%(provides)s'" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Sem campo de arquitetura no pacote" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Arquitetura incorreta '%s'" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Uma versão mais atual já está instalada" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Falha na satisfação de todas as dependências (cache quebrado)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "Incapaz de instalar '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Descompactado automaticamente:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Convertido automaticamente para ascii imprimível:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"Instalar dependências construtivas para o pacote fonte '%s' que constrói %s\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Um pacote essencial teria de ser removido" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Feito" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Atingido " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Ignorando " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Erro " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Obtendo:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [Trabalhando]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Mudança de mídia: por favor, insira o disco de nome\n" +"'%s'\n" +"no drive '%s' e tecle Enter\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Obtidos %sB em %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" +"Por favor, forneça um nome para este disco, como 'Debian 6.0.1 Disco 1'" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Por favor, insira um disco no drive e tecle Enter" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Construindo estruturas de dados" + +#~ msgid "Python-debian module not available" +#~ msgstr "Módulo python-debian não disponível" + +#~ msgid "Failed to fetch %s %s\n" +#~ msgstr "Falha ao buscar %s, %s\n" + +#~ msgid "--fix-missing and media swapping is not currently supported" +#~ msgstr "--fix-missing e troca de mídia não são suportados atualmente" + +#~ msgid "This is not a valid DEB archive, missing '%s' member" +#~ msgstr "Este não é um arquivo DEB válido, membro '%s' faltando" diff --git a/po/python-apt.pot b/po/python-apt.pot new file mode 100644 index 0000000..a422fa1 --- /dev/null +++ b/po/python-apt.pot @@ -0,0 +1,365 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2023-11-22 15:35+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:33 +msgid "Ubuntu development series" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:112 +msgid "Canonical-supported free and open-source software" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:114 +msgid "Community-maintained" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:115 +msgid "Community-maintained free and open-source software" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:117 +msgid "Non-free drivers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:118 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:121 +msgid "Restricted software" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:122 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:129 +msgid "Ubuntu {version} '{codename}'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:137 +msgid "Installation medium with Ubuntu {version} '{codename}'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:140 ../data/templates/Debian.info.in:113 +msgid "Officially supported" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:142 +msgid "Restricted copyright" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:149 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:151 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:152 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:160 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:162 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:163 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:182 +msgid "Important security updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:195 ../data/templates/Debian.info.in:53 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:208 +msgid "Pre-released updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:221 +msgid "Unsupported updates" +msgstr "" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "" +"https://metadata.ftp-master.debian.org/changelogs/%s/%s/%s/%s_%s_changelog" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:25 +msgid "Debian {version} '{codename}'" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:47 +msgid "Security updates" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:59 +msgid "Proposed updates" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:66 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:81 +msgid "Debian testing" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:111 +msgid "Debian 'Sid' (unstable)" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:115 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:117 +msgid "Non-DFSG-compatible Firmware for Hardware Support" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:119 +msgid "Non-DFSG-compatible Software" +msgstr "" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:461 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:225 ../aptsources/distro.py:237 +#: ../aptsources/distro.py:258 +msgid "Main server" +msgstr "" + +#: ../aptsources/distro.py:267 +msgid "Custom servers" +msgstr "" + +#: ../apt/package.py:619 +#, python-format +msgid "Missing description for '%s'.Please report." +msgstr "" + +#: ../apt/package.py:629 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1330 ../apt/package.py:1346 ../apt/package.py:1459 +#: ../apt/package.py:1475 +msgid "The list of changes is not available" +msgstr "" + +#: ../apt/package.py:1467 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1482 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" + +#: ../apt/debfile.py:96 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:108 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:242 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:272 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#: ../apt/debfile.py:434 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#: ../apt/debfile.py:465 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:482 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:543 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:555 +#, python-format +msgid "" +"Wrong architecture '%s' -- Run dpkg --add-architecture to add it and update " +"afterwards" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:570 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:596 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:627 +#, python-format +msgid "Cannot install '%s'" +msgstr "" + +#: ../apt/debfile.py:707 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:713 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:824 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:838 +msgid "An essential package would be removed" +msgstr "" + +#: ../apt/progress/text.py:97 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:143 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:153 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:155 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:167 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:238 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:252 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#: ../apt/progress/text.py:267 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:291 +msgid "Please provide a name for this medium, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:312 +msgid "Please insert an installation medium and press enter" +msgstr "" diff --git a/po/ro.po b/po/ro.po new file mode 100644 index 0000000..05885f0 --- /dev/null +++ b/po/ro.po @@ -0,0 +1,663 @@ +# Romanian translation of update-manager. +# Copyright (C) 2005 Free Software Foundation, Inc. +# This file is distributed under the same license as the update-manager package. +# Dan Damian , 2005. +# +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:13+0000\n" +"Last-Translator: Sami POTIRCA \n" +"Language-Team: Romanian \n" +"Language: ro\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3;plural=(n==1?0:(n==0||((n%100)>0&&(n%100)<20))?" +"1:2)\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Actualizări de Securitate Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Cdrom cu Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Cdrom cu Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Cdrom cu Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Cdrom cu Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Cdrom cu Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Cdrom cu Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Cdrom cu Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Cdrom cu Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Cdrom cu Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Actualizări de Securitate Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Cdrom cu Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Actualizări de Securitate Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Cdrom cu Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Pachete întreţinute de comunitate (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +#, fuzzy +msgid "Restricted software" +msgstr "Software în contribuţie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Cdrom cu Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Pachete întreţinute de comunitate (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Pachete întreţinute de comunitate (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Pachete întreţinute de comunitate (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Pachete non-libere" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Software restricţionat (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Cdrom cu Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Actualizări importante de securitate" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Actualizări recomandate" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Pachete propuse" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Actualizări portate înapoi" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Cdrom cu Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Actualizări de Securitate Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Actualizări Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Cdrom cu Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Pachete suportate oficial" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Actualizări de Securitate Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Actualizări Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Pachete întreţinute de comunitate (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Pachete non-libere (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Cdrom cu Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +#, fuzzy +msgid "No longer officially supported" +msgstr "Pachete suportate oficial" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Copyright restrictiv" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Actualizări de securitate Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Actualizări Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 Backports" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Pachete propuse" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Actualizări importante de securitate" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Software compatibil DFSG cu dependenţe negratuite" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Software incompatibil DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Server pentru %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Server principal" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Servere preferenţiale" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detalii" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Lista schimbărilor nu este disponibilă" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Nu am putut descărca lista modificărilor. Vă rog să verificaţi dacă aveţi o " +"conexiune internet activă." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Nu pot instala '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Un pachet esenţial ar trebui şters" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/ru.po b/po/ru.po new file mode 100644 index 0000000..4a457f0 --- /dev/null +++ b/po/ru.po @@ -0,0 +1,665 @@ +# Russian translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# Igor Zubarev , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2006-10-18 09:11+0000\n" +"Last-Translator: Igor Zubarev \n" +"Language-Team: Russian \n" +"Language: ru\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Диск с Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Диск с Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Диск с Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Диск с Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Партнеры Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Програмное обеспечение упаковано Canonical для партнеров" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Это програмное обеспечение не является частью Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Независимый" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Предоставлено сторонними разработчиками." + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Програмное обеспечение предлагается сторонними разработчиками." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Диск с Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Диск с Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Диск с Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Диск с Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Диск с Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Обновления безопасности Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Диск с Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Диск с Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Поддерживается сообществом" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Несвободное ПО" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CDROM с Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Open Source приложения, поддерживаемые Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Поддерживается сообществом (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Поддерживаемое сообществом свободное ПО" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Несвободные драйвера" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Проприетарные драйвера устройств" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Несвободное обеспечение (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Программы, ограниченные патентами или законами" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CD с Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Важные обновления безопасности" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Рекомендованые обновления" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Пред-релизные обновления" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Не поддерживаемые обновления" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD с Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Обновления безопасности Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Обновления Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD с Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Официально поддерживается" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Обновления безопасности Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Обновления Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 бэкпорты" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Поддерживается сообществом (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Несвободное (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD с Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Официально больше не поддерживается" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Ограниченные авторские права" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Обновления безопасности Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Обновления Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 бэкпорты" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 'Wheezy' " + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 'Squeeze' " + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 'Lenny' " + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 'Etch'" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 'Sarge'" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Предлагаемые обновления" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Обновления безопасности" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Текущий стабильный релиз Debian" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian testing" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian 'Sid' (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-совместимое ПО с зависимостями от несвободного ПО" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Не-DFSG-совместимое ПО" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Сервер %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Основной сервер" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Свои сервера" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Загрузка файла %(current)li из %(total)li со скоростью %(speed)s/с" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Загрузка файла %(current)li из %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Подробности" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Начинаем..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Завершено" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "Неправильный unicode в описании '%s' (%s). Пожалуйста, сообщите." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Список изменений недоступен или отсутствует." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"Список изменений еще недоступен.\n" +"\n" +"Пожалуйста используйте http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"до тех пор, пока изменения не станут доступны или попробуйте позже." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Ошибка при загрузке списка изменений. \n" +"Пожалуйста, проверьте ваше соединение с Интернет." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Список файлов для '%s' не может быть прочтен" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Список контролирующих файлов для '%s' не может быть прочтен" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Неразрешимая зависимость: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Конфликт с установленым пакетом '%s'" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Ломает в существующем пакете '%(pkgname)s' зависимость %(depname)s " +"(%(deprelation)s %(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Ломает существующий пакет '%(pkgname)s' конфликтует с: %(targetpkg)s " +"(%(comptype)s %(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Нет указания архитектуры в пакете" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Неправильная архитектура '%s'" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Более поздняя версия уже установлена" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Неудалось определить все зависимости (broken cache)" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Невозможно установить '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Будет удален необходимый пакет" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/sk.po b/po/sk.po new file mode 100644 index 0000000..a34b84b --- /dev/null +++ b/po/sk.po @@ -0,0 +1,638 @@ +# Slovak translation for update-manager +# Copyright (C) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# Peter Chabada , 2006. +# Ivan Masár , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2012-06-10 23:28+0100\n" +"Last-Translator: Ivan Masár \n" +"Language-Team: Slovak \n" +"Language: sk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural= (n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 „Precise Pangolin“" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "CD-ROM s Ubuntu 12.04 „Precise Pangolin“" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 „Oneiric Ocelot“" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "CD-ROM s Ubuntu 11.10 „Oneiric Ocelot“" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 „Natty Narwhal“" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "CD-ROM s Ubuntu 11.04 „Natty Narwhal“" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 „Maverick Meerkat“" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "CD-ROM s Ubuntu 10.10 „Maverick Meerkat“" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Partneri Canonicalu" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Balíky softvéru, ktoré pripravil Canonical pre svojich partnerov" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Tento softvér nie je súčasťou Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Nezávislé" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Poskytované vývojármi tretích strán" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Softvér, ktorý ponúkajú vývojári tretích strán." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 „Lucid Lynx“" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "CD-ROM s Ubuntu 10.04 „Lucid Lynx“" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 „Karmic Koala“" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "CD-ROM s Ubuntu 9.10 „Karmic Koala“" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 „Jaunty Jackalope“" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "CD-ROM s Ubuntu 9.04 „Jaunty Jackalope“" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 „Intrepid Ibex“" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Disk s Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 „Hardy Heron“" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "CD-ROM s Ubuntu 8.04 „Hardy Heron“" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 „Gutsy Gibbon“" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "CD-ROM s Ubuntu 7.10 „Gutsy Gibbon“" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 „Feisty Fawn“" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "CD-ROM s Ubuntu 7.04 „Feisty Fawn“" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 „Edgy Eft“" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Udržiavané komunitou" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Softvér závislý na neslobodnom softvéri" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "CD-ROM s Ubuntu 6.10 „Edgy Eft“" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS „Dapper Drake“" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Slobodný a open source softvér, ktorý podporuje Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Udržiavané komunitou (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Slobodný a open source softvér udržiavaný komunitou" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Neslobodné ovládače" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Proprietárne ovládače zariadení" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Neslobodný softvér (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Softvér obmedzený autorskými právami alebo právnymi otázkami" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "CD-ROM s Ubuntu 6.06 LTS „Dapper Drake“" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Dôležité bezpečnostné aktualizácie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Odporúčané aktualizácie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Aktualizácie pred vydaním" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Nepodporované aktualizácie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "CD-ROM s Ubuntu 5.10 „Breezy Badger“" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 - bezpečnostné aktualizácie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 - aktualizácie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 - backporty" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 „Hoary Hedgehog“" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "CD-ROM s Ubuntu 5.04 „Hoary Hedgehog“" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Oficiálne podporované" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 - bezpečnostné aktualizácie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 - aktualizácie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 - backporty" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 „Warty Warthog“" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Udržiavané komunitou (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Neslobodné (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "CD-ROM s Ubuntu 4.10 „Warty Warthog“" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Už nie sú oficiálne podporované" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "S obmedzujúcou licenciou" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 bezpečnostné aktualizácie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 aktualizácie" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 - backporty" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 „Wheezy“ " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 „Squeeze“ " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 „Lenny“ " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 „Etch“" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 „Sarge“" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Navrhované aktualizácie" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Bezpečnostné aktualizácie" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Aktuálne vydanie Debian stable" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian testing" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian „Sid“ (nestabilné)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Softvér kompatibilný s DFSG bez závislostí na neslobodnom softvére" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Softvér nekompatibilný s DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Server pre %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Hlavný server" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Vlastné servery" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Sťahuje sa súbor %(current)li z %(total)li pri %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Sťahuje sa súbor %(current)li z %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Podrobnosti" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Spúšťa sa..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Hotovo" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "Neplatný Unicode v pospise „%s“ (%s). Nahláste to, prosím." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Zoznam zmien nie je k dispozícii" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"Zoznam zmien zatiaľ nie je dostupný.\n" +"\n" +"Prosím, použite http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"pokým zmeny nebudú dostupné alebo to skúste znova neskôr." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Nepodarilo sa stiahnuť zoznam zmien. \n" +"Prosím, skontrolujte si svoje pripojenie k internetu." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Zoznam súborov „%s“ nebolo možné načítať" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Zoznam riadiacich súborov „%s“ nebolo možné načítať" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Závislosť nemožno uspokojiť: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Je v konflikte s nainštalovaným balíkom „%s“" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Kazí závislosť %(depname)s (%(deprelation)s %(depversion)s) existujúceho " +"balíka „'%(pkgname)s“" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Kazí konflikt %(targetpkg)s (%(comptype)s %(targetver)s) existujúceho balíka " +"„'%(pkgname)s“" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Kazí existujúci balík „'%(pkgname)s“, ktorý je v konflikte s: " +"„'%(targetpkg)s“. Ale „'%(debfile)s“ ho poskytuje prostredníctvom " +"„'%(provides)s“" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Balíku chýba pole Architecture (architektúra)" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Nesprávna architektúra „%s“" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Novšia verzia už je nainštalovaná" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" +"Nepodarilo sa uspokojiť všetky závislosti (poškodená vyrovnávacia pamäť)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "Nie je možné bainštalovať „%s“" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Automaticky rozbalené:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Automaticky prevedené na tlačiteľné znaky ASCII:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"Nainštalovať závislosti zostavenia zdrojového balíka „%s“, ktorý zostavuje " +"%s\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Bol by odstránený nevyhnutný balík" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Hotovo" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Stiah " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Ignor " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Chyba " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Získať:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [Pracuje sa]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Výmena média: prosím, vložte disk s označením\n" +" „%s“\n" +"do mechaniky „%s“ a stlačte Enter\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Stiahnutých %sB za %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "Prosím, zadajte názov tohto disku. Napr. „Debian 2.1r1 Disk 1“" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Prosím, vložte disk do mechaniky a stlačte Enter" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Zostavujú sa údajové štruktúry" diff --git a/po/sl.po b/po/sl.po new file mode 100644 index 0000000..3c67f3e --- /dev/null +++ b/po/sl.po @@ -0,0 +1,649 @@ +# Slovenian translation for python-apt-rosetta. +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the python-apt-rosetta package. +# +# Matej Urbančič , 2006 - 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: python-apt-rosetta\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2012-06-10 22:24+0100\n" +"Last-Translator: Matej Urbančič \n" +"Language-Team: Slovenian \n" +"Language: sl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n" +"%100==4 ? 3 : 0);\n" +"X-Launchpad-Export-Date: 2010-12-03 00:21+0000\n" +"X-Generator: Launchpad (build Unknown)\n" +"X-Poedit-Language: Slovenian\n" +"X-Poedit-Country: SLOVENIA\n" +"X-Poedit-SourceCharset: utf-8\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "xUbuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Nosilec CD z Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "xUbuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Nosilec CD z Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "xUbuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Nosilec CD z Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Nosilec CD z Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Partnerske ustanove Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Programska oprema Canonical za partnerske ustanove" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Programska opreme ni del distribucije Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Neodvisno" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Programska oprema, ki jo objavljajo razvijalci skupnosti" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Programska oprema tretje roke." + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Nosilec CD z Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Nosilec CD z Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Nosilec CD z Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Nosilec CD z Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Nosilec CD z Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Nosilec CD z Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Nosilec CD z Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Paketi skupnosti" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Avtorsko omejena programska oprema" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Nosilec CD z Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Odprtokodna programska oprema podprta s strani Canonical Ltd" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Paketi skupnosti (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Programska oprema, ki jo vzdržuje odprtokodna skupnost" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Neprosti gonilniki" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Lastniški gonilniki za naprave" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Avtorsko omejena programska oprema (multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" +"Programska oprema, ki je omejena z avtorskimi pravicami ali drugimi pravnimi " +"vidiki" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Nosilec CD z Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Pomembne varnostne posodobitve" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Priporočene posodobitve" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Predhodno izdane posodobitve" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Nepodprte posodobitve" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Nosilec CD z Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 varnostne posodobitve" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 posodobitve" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 postarani paketi" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Nosilec CD z Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Uradno podprto" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 varnostne posodobitve" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 posodobitve" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 postarani paketi" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Paketi skupnosti (universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Ne-prosti paketi (multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Nosilec CD z Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Brez uradne podpore" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Omejeno z avtorskimi pravicami" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 varnostne posodobitve" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 posodobitve" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 postarani paketi" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 'Wheezy' " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 'Squeeze' " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 'Lenny' " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 'Etch'" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 'Sarge'" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Predlagane posodobitve" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Varnostne posodobitve" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Debian trenutna stabilna različica" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian preizkusna različica" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (razvojna različica)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Program je skladen z DFSG-compatible ne prostimi odvisnostmi" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Program ni skladen z DFSG" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Strežnik za %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Glavni strežnik" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Strežniki po meri" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" +"Prejemanje datoteke %(current)li od skupno %(total)li s hitrostjo %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Prejemanje datoteke %(current)li od skupno %(total)li." + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Podrobnosti" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Začenjanje ..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Končano" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" +"Neveljaven znak unikod v opisu za '%s' (%s). Pošljite poročilo o napaki." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Seznam sprememb ni na voljo" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"Seznam sprememb še ni na voljo.\n" +"\n" +"Več podrobnosti je na http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"dokler dnevnik ne bo posodobljen ali pa poskusite kasneje." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Prejemanje seznama sprememb je spodletelo.\n" +"Preverite internetno povezavo." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Seznama datotek za '%s' ni mogoče prebrati" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Nadzornega seznama datotek za '%s' ni mogoče prebrati" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Odvisnost ni razrešena: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Spor z nameščenim paketom '%s'" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Pokvari odvisnost obstoječega paketa '%(pkgname)s' %(depname)s " +"(%(deprelation)s %(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Pokvari spor obstoječega paketa '%(pkgname)s': %(targetpkg)s (%(comptype)s " +"%(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Pokvari obstoječi paket '%(pkgname)s', ki je v sporu s paketom: " +"'%(targetpkg)s'. Paket '%(debfile)s' ga zagotavlja preko: '%(provides)s'" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "V paketu ni polja določila arhitekture sistema" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Napačna arhitektura '%s'" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Novejša različica je že nameščena." + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Ni mogoče razrešiti vseh odvisnosti (napaka v predpomnilniku)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "Ni mogoče namestiti '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Samodejno razširjeno:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Samodejno pretvorjeno v zapis ASCII:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"Namestiti je treba pakete za izgradnjo iz izvorne kode '%s' s katerimi je " +"mogoče izgraditi %s\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Z dejanjem bi bil odstranjen sistemski paket" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s ... Končano." + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Zad " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Prz " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Nap " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Pridobi:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [V delovanju]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Zamenjava nosilca: vstavite disk z oznako\n" +" '%s'\n" +"v enoto '%s' in pritisnite vnosno tipko\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Pridobljenih %sB v %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "Poimenujte disk, na primer 'Debian 2.1r1 Disk 1'" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Vstavite disk v pogon in pritisnite vnosno tipko" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Izgradnja podatkovnega drevesa" + +#~ msgid "Python-debian module not available" +#~ msgstr "Modul Python-debian ni na voljo" diff --git a/po/sq.po b/po/sq.po new file mode 100644 index 0000000..5bf5e5d --- /dev/null +++ b/po/sq.po @@ -0,0 +1,623 @@ +# Albanian translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-09 15:50+0000\n" +"Last-Translator: Alejdin Tirolli \n" +"Language-Team: Albanian \n" +"Language: sq\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "%s përmirësimet" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "%s përmirësimet" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Serveri për %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +#, fuzzy +msgid "Main server" +msgstr "Serveri më i afërt" + +#: ../aptsources/distro.py:250 +#, fuzzy +msgid "Custom servers" +msgstr "Serveri më i afërt" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +#, fuzzy +msgid "Details" +msgstr "Përditë" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "'%s' nuk mund të instalohet" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Një paketë themelore u deshtë të largohej" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/sr.po b/po/sr.po new file mode 100644 index 0000000..7e2fbca --- /dev/null +++ b/po/sr.po @@ -0,0 +1,648 @@ +# Serbian translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2006-10-16 04:17+0000\n" +"Last-Translator: Nikola Nenadic \n" +"Language-Team: Serbian \n" +"Language: sr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Оптички диск са Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Оптички диск са 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Оптички диск са Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Оптички диск са Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Canonical партнери" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Софтвер упакован од Canonical за њихове партнере" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Овај софтвер није дио Ubuntu" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Независан" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Обезбјеђен од независних програмера софтвера" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Софтвер је понуђен од независних програмера софтвера" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Оптички диск са Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Оптички диск са Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 'Jaunty Jackalope" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Оптички диск са Ubuntu 9.04 'Jaunty Jackalope" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Оптички диск са Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Оптички диск са Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Оптички диск са Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Оптички диск са Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Одржаван од стране заједнице" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Ограничени софтвер" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Оптички диск са Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Canonical-подржава слободан софтвер и софтвер отвореног кода" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Одржаван од стране заједнице" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Заједница одржава слободан софтвер и софтвер отвореног кода" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Комерцијални драјвери" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Власнички драјвери за уређаје" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Ограничени софтвер" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Софтвер ограничен ауторским правом или правним регулативама" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Оптички диск са Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Важне сигурносне исправке" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Препоручено ажурирање" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Унапријед објављене исправке" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Некомпитабилна ажурирања" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Оптички диск са Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 сигурносне исправке" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 исправке" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Оптички диск са Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Званично подржани" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 Исправке" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Одржаван од стране заједнице" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Не слободн драјвери" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Оптички диск са Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Званично није више подржано" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Ограничена права" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 сигурносне исправке" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 Исправке" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 Backports" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 'Wheezy' " + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 'Squeeze'" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 'Lenny'" + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 'Etch'" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 'Sarge'" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Предложене исправке (ажурирања)" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Сигурносне исправке" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Дебиан-тренутно стабилно издање" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Дебиан-тестирање" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian 'Sid' (нестабилно)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-компитабилан са не слободним софтвером" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Непостоји-DFSG компитабилног софтвера" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Сервер за %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Главни сервер" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Прилагођени сервер" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Преузимам фајл %(current)li од %(total)li са %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Преузимам фајл %(current)li од %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Детаљи" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Покретање..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Завршено" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "Неважећи unicode у опису за '%s' (%s). Молим извјештај" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Листа промјена није доступна" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"Листа промјена није још доступна.\n" +"Молимо искористите http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"док промјене не постану доступне или покушајте поново касније." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Преузиманје листе промјена неуспјешно. \n" +"Молимо провјерите своју конекцију са интернетом." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Листа фајлова за '%s' не може да се прочита" + +#: ../apt/debfile.py:93 +#, fuzzy, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Листа фајлова за '%s' не може да се прочита" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Зависнот није задовољена: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Сукоби међу инсталираним пакетима '%s'" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Прекид постојања пакета '%(pkgname)s' зависи од %(depname)s (%(deprelation)s " +"%(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Прекид постојања пакета '%(pkgname)s' конфликт: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" + +#: ../apt/debfile.py:399 +#, fuzzy, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Прекид посојања пакета '%(pkgname)s' који је иѕаѕвао конфликт: " +"'%(targetpkg)s'. Али '%(targetpkg)s' га даје преко: '%(provides)s'" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Нема поља архитектуре у пакету" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Погрешна архитектура '%s'" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Новија верзија је већ инсталирана" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Није успео да задовољи све зависности (грешка у кешу)" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Не могу да се инсталирају %s" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "Аутомацка декомпресија:\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Аутомацко пребацивање за штампање ascii:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "Инсталирајте Build-Dependencies за кодни пакет '%s' који гради %s\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Битан пакет би био уклоњен" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Крај" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Погодак" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Игнорисано" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Грешка" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Узимам:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "[Радим]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Молимо вас да убаците означени диск\n" +" у оптички диск '%s' и притиснете enter\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Преузето %sB in %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "Молимо обезбједите име за диск, као нпр. 'Debian 2.1r1 Disk 1'" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Молимо Вас да убаците диск у оптички уређај и притиснете enter" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Изградња структуре података" + +#~ msgid "This is not a valid DEB archive, missing '%s' member" +#~ msgstr "Ово није валидна DEB архива, недостаје '% с' члан" diff --git a/po/sv.po b/po/sv.po new file mode 100644 index 0000000..08e858b --- /dev/null +++ b/po/sv.po @@ -0,0 +1,662 @@ +# Swedish messages for update-manager. +# Copyright (C) 2005 Free Software Foundation, Inc. +# Daniel Nylander , 2006. +# Christian Rose , 2005. +# +# $Id: sv.po,v 1.5 2005/04/04 08:49:52 mvogt Exp $ +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 05:06+0000\n" +"Last-Translator: Daniel Nylander \n" +"Language-Team: Swedish \n" +"Language: sv\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Säkerhetsuppdateringar för Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Cd-rom med Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Cd-rom med Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Cd-rom med Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Cd-rom med Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Cd-rom med Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Cd-rom med Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Cd-rom med Ubuntu 4.10 \"Warty Warthog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Cd-rom med Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Cd-rom med Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Säkerhetsuppdateringar för Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Cd-rom med Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Säkerhetsuppdateringar för Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Cd-rom med Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 \"Edgy Eft\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Gemenskapsunderhållen" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Inskränkt programvara" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Cd-rom med Ubuntu 6.10 \"Edgy Eft\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS \"Dapper Drake\"" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Öppen källkodsprogramvara som stöds av Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Gemenskapsunderhållen (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Öppen källkodsprogramvara underhållen av gemenskapen" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Ickefria drivrutiner" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Properitära drivrutiner för enheter" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Inskränkt programvara (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Programvara begränsad av upphovsrätt eller juridiska avtal" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Cd-rom med Ubuntu 6.06 LTS \"Dapper Drake\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Viktiga säkerhetsuppdateringar" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Rekommenderade uppdateringar" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Föreslagna uppdateringar" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Bakåtporterade uppdateringar" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Cd-rom med Ubuntu 5.10 \"Breezy Badger\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 Säkerhetsuppdateringar" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 Uppdateringar" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Bakåtportar" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Cd-rom med Ubuntu 5.04 \"Hoary Hedgehog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Stöds officiellt" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Säkerhetsuppdateringar för Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Uppdateringar för Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Bakåtporteringar för Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Gemenskapsunderhållen (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Ickefri (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Cd-rom med Ubuntu 4.10 \"Warty Warthog\"" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Stöds inte längre officiellt" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Begränsad upphovsrätt" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Säkerhetsuppdateringar för Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Uppdateringar för Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Bakåtporteringar för Ubuntu 4.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Föreslagna uppdateringar" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Viktiga säkerhetsuppdateringar" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (testing)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "DFSG-kompatibel programvara med icke-fria beroenden" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Icke-DFSG-kompatibel programvara" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Server för %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Huvudserver" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Anpassade servrar" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Hämtar fil %(current)li av %(total)li med %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Hämtar fil %(current)li av %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Detaljer" + +#: ../apt/progress/gtk2.py:428 +#, fuzzy +msgid "Starting..." +msgstr "Söker..." + +#: ../apt/progress/gtk2.py:434 +#, fuzzy +msgid "Complete" +msgstr "Komponenter" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Listan över ändringar finns inte tillgänglig" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Misslyckades med att hämta listan över ändringar. \n" +"Kontrollera din Internetanslutning." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, fuzzy, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Beroendeupplösning misslyckades" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Kan inte installera \"%s\"" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Ett grundläggande paket skulle behöva tas bort" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/th.po b/po/th.po new file mode 100644 index 0000000..bfc7ca6 --- /dev/null +++ b/po/th.po @@ -0,0 +1,659 @@ +# Thai translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:17+0000\n" +"Last-Translator: Roys Hengwatanakul \n" +"Language-Team: Thai \n" +"Language: th\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "อูบันตู 5.04 ปรับปรุงด้านความปลอดภัย" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "ซีดีรอมที่มี อูบันตู 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "อูบันตู 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "ซีดีรอมที่มีอูบันตู 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "อูบันตู 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "ซีดีรอมที่มีอูบันตู 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "อูบันตู 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "ซีดีรอมที่มีอูบันตู 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "อูบันตู 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "ซีดีรอมที่มีอูบันตู 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "อูบันตู 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "ซีดีรอมที่มีอูบันตู 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "อูบันตู 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "ซีดีรอมที่มีอูบันตู 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "อูบันตู 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "ซีดีรอมที่มีอูบันตู 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "อูบันตู 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "ซีดีรอมที่มีอูบันตู 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "อูบันตู 5.04 ปรับปรุงด้านความปลอดภัย" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "ซีดีรอมที่มี อูบันตู 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "อูบันตู 5.04 ปรับปรุงด้านความปลอดภัย" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "ซีดีรอมที่มี อูบันตู 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "อูบันตู 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "ชุมชนดูแล" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "ซอฟต์แวร์จำกัดการใช้งาน" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "ซีดีรอมที่มีอูบันตู 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "อูบันตู 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "ซอฟต์แบบเปิดเผยสนับสนุนโดย Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "ชุมชนดูแล (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "ชุมชนดูแล ซอฟต์แวร์แบบเปิดเผย" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "ไดรเวอร์ที่ไม่ฟรี" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "ไดรเวอร์ที่มีกรรมสิทธิ์สำหรับอุปกรณ์" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "ซอฟต์แวร์จำกัดการใช้งาน(Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "ซอฟต์แวร์นี้มีลิขสิทธ์หรือข้อกฏหมายจำกัดอยู่" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "ซีดีรอมที่มีอูบันตู 6.06 LST 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "ปรับปรุงด้านความปลอดภัยที่สำคัญ" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "การปรับปรุงที่แนะนำให้ทำ" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "การปรับปรุงที่เสนอให้ทำ" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "การปรับปรุงแบบย้อนหลัง" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "อูบันตู 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "ซีดีรอมที่มี อูบันตู 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "อูบันตู 5.10 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "อูบันตู 5.10 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "อูบันตู 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "อูบันตู 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "ซีดีรอมที่มีอูบันตู 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "สนับสนุนอย่างเป็นทางการ" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "อูบันตู 5.04 ปรับปรุงด้านความปลอดภัย" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "อูบันตู 5.04 ปรับปรุง" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "อูบันตู 5.04 พอร์ตย้อนหลัง" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "อูบันตู 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "ชุมชนดูแล (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "ไม่ฟรี(ลิขสิทธิ์)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "ซีดีรอมที่มีอูบันตู 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "ไม่ได้รับการสนับสนุนอย่างเป็นทางการแล้ว" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "จำกัดลิขสิทธิ์" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "อูบันตู 4.10 ปรับปรุงด้านความปลอดภัย" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "อูบันตู 4.10 ปรับปรุง" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "อูบันตู 4.10 พอร์ตย้อนหลัง" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "เดเบียน 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "เดเบียน 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "เดเบียน 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "เดเบียน 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "เดเบียน 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "การปรับปรุงที่เสนอให้ทำ" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "ปรับปรุงด้านความปลอดภัยที่สำคัญ" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "เดเบียน \"Etch\" (กำลังทดสอบ)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "เดเบียน \"Sid\" (ผันผวน)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "เข้ากับ DFSG ซอฟแวร์แต่ขึ้นอยู่กับไม่ฟรี" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "ไม่เข้ากับ DFSG ซอฟแวร์" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "เซิร์ฟเวอร์สำหรับประเทศ %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "เซิร์ฟเวอร์หลัก" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "เซิร์ฟเวอร์ที่กำหนดเอาเอง" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" +"กำลังดาวน์โหลดไฟล์ที่ %(current)li จากทั้งหมด %(total)li ด้วยความเร็ว %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "กำลังดาวน์โหลดไฟล์ที่ %(current)li จากทั้งหมด %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "รายละเอียด" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "รายการของการเปลี่ยนแปลงยังไม่มีให้" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"ไม่สามารถดาวน์โหลดรายการของการเปลี่ยนแปลง \n" +"กรุณาตรวจสอบการสื่อสารทางอินเตอร์เน็ตของคุณ" + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "ไม่สามารถติดตั้ง '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "แพจเกจที่สำคัญจะถูกลบออก" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/tl.po b/po/tl.po new file mode 100644 index 0000000..3273376 --- /dev/null +++ b/po/tl.po @@ -0,0 +1,639 @@ +# Tagalog translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:42+0200\n" +"PO-Revision-Date: 2012-06-11 11:13+0800\n" +"Last-Translator: Ariel S. Betan \n" +"Language-Team: Tagalog \n" +"Language: tl\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n > 1\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Cdrom na may Ubuntu 12.04 'Precise Pangolin'" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Cdrom na may Ubuntu 11.10 'Oneiric Ocelot'" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Cdrom na may Ubuntu 11.04 'Natty Narwhal'" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Cdrom na may Ubuntu 10.10 'Maverick Meerkat'" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "Mga Kasama ng Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "Software na pinakete ng Canonical para sa kanilang mga kasama" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "Ang software na ito ay hindi bahagi ng Ubuntu." + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "Malaya" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "Ipinamahagi ng mga third-party software developers" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "Software na ibinigay mga third party developers " + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Cdrom na may Ubuntu 10.04 'Lucid Lynx'" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Cdrom na may Ubuntu 9.10 'Karmic Koala'" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Cdrom na may Ubuntu 9.04 'Jaunty Jackalope'" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Cdrom na may Ubuntu 8.10 'Intrepid Ibex'" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Cdrom na may Ubuntu 8.04 'Hardy Heron'" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Cdrom na may Ubuntu 7.10 'Gutsy Gibbon'" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Cdrom na may Ubuntu 7.04 'Feisty Fawn'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "Inaalagaan ng kumunidad" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Software na may mahigpit na gamit" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Cdrom na may Ubuntu 6.10 'Edgy Eft'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +msgid "Canonical-supported free and open-source software" +msgstr "Malaya at bukas na software suportado ng Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "Inaalagaan ng kumunidad (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +msgid "Community-maintained free and open-source software" +msgstr "Malaya at bukas na software suportado ng Canonical" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Hindi malayang drivers" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Proprietary drivers para sa mga devices" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Software na may mahigpit na gamit (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" +"Software na may mahigpit na gamit dahil sa copyright o mga legal issues" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Cdrom na may Ubuntu 6.06 LTS 'Dapper Drake'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Mga mahalagang updates pang-seguridad" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Mga mungkahing updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "Mga updates bago ma-released" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "Mga hindi suportadong updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Cdrom na may Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Cdrom na may Ubuntu 5.04 'Hoary Hedgehog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Opisyal na sinusuportahan" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "Inaalagaan ng kumunidad (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Di-malaya (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Cdrom na may Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Hindi na opisyal na sinusuportahan" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Mahigpit na copyright" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 Security Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 Updates" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 Backports" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +msgid "Debian 7 'Wheezy' " +msgstr "Debian 7 'Wheezy' " + +#. Description +#: ../data/templates/Debian.info.in:33 +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 6.0 'Squeeze' " + +#. Description +#: ../data/templates/Debian.info.in:58 +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 5.0 'Lenny' " + +#. Description +#: ../data/templates/Debian.info.in:83 +msgid "Debian 4.0 'Etch'" +msgstr "Debian 4.0 'Etch'" + +#. Description +#: ../data/templates/Debian.info.in:108 +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 'Sarge'" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Mga mungkahing updates" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "Mga updates pang-seguridad" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "Kasalukuyang stable release ng Debian" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian testing" + +#. Description +#: ../data/templates/Debian.info.in:172 +msgid "Debian 'Sid' (unstable)" +msgstr "Debian 'Sid' (unstable)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Software na DFSG-compatible na may Di-Malayang mga Dependensiya" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "Software na Di-DFSG-compatible" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "Server para sa %s" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Pangunahing server" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Pasadyang mga servers" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Downloading file %(current)li of %(total)li with %(speed)s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Downloading file %(current)li of %(total)li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Mga Detalye" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "Nagsisimula..." + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "Kumpleto" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" +"Invalidong unicode sa deskripsyon para '%s' (%s). Mangyaring ipagbigay alam." + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Ang talaan ng mga pagbabago ay wala" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" +"Ang talaan ng mga pagbabago ay wala pa.\n" +"\n" +"Mangyaring gamitin http://launchpad.net/ubuntu/+source/%s/%s/+changelog\n" +"hanggang mayroon ng mga pagbabago o subukang muli mamaya." + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Bigo sa pag-download ng talaan ng mga pagbabago. \n" +"Mangyaring suriin ang inyong koneksyon sa internet." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "Ang talaan ng mga files para sa '%s' ay hindi mabasa" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "Ang talaan ng mga files na pang-kontrol para sa '%s' ay hindi mabasa" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "Ang Dependensiya ay hindi sapat: %s\n" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "Mga mga conflicts sa na-install na paketeng '%s'" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" +"Binabasag ang umiiral na paketeng '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" +"Binabasag ang umiiral na paketeng '%(pkgname)s' conflict: %(targetpkg)s " +"(%(comptype)s %(targetver)s)" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" +"Binabasag ang umiiral na paketeng '%(pkgname)s' na may conflict sa: " +"'%(targetpkg)s'. Ngunit ang '%(debfile)s' ay nagbibigay nito sa pamamagitan " +"ng: '%(provides)s'" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "Walang Architecture field sa loob ng pakete" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "Maling architecture '%s'" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "Mas naunang bersiyon ang kasalukuyang naka-install" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "Bigo na maging sapat ang lahat ng dependensiya (broken cache)" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "Hindi ma-install '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" +"Automatikong na decompressed:\n" +"\n" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "Automatikong na-convert sa printable ascii:\n" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" +"Install Build-Dependencies para sa pinagmulang pakete '%s' na nag-build ng " +"%s\n" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "Isang kinakailangang pakete ang kailangang tanggalin" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "%c%s... Tapos na" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "Hit " + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "Ign " + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "Err " + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "Kunin:" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr " [Nagtatrabaho]" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" +"Bagong media: magyaring ipasok ang disc na may label na\n" +" '%s'\n" +"sa drive '%s' at pindutin ang enter\n" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "Kinuha %sB sa %s (%sB/s)\n" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" +"Mangyaring magbigay ng pangalan para sa Disc, tulad ng 'Debian 2.1r1 Disk 1'" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Mangyaring magpasok ng Disc sa drive at pindutin ang enter" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "Nagbubuo ng data structures" diff --git a/po/tr.po b/po/tr.po new file mode 100644 index 0000000..aea4661 --- /dev/null +++ b/po/tr.po @@ -0,0 +1,659 @@ +# Turkish translation for update-manager +# Copyright (c) (c) 2006 Canonical Ltd, and Rosetta Contributors 2006 +# This file is distributed under the same license as the update-manager package. +# FIRST AUTHOR , 2006. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: update-manager\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-21 20:58+0000\n" +"Last-Translator: Atilla Karaman \n" +"Language-Team: Turkish \n" +"Language: tr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.04 Güvenlik Güncelleştirmeleri" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.10 'Breezy Badger' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 'Warty Warthog' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Warty Warthog' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Warty Warthog' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Warty Warthog' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Warty Warthog' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.04 Güvenlik Güncelleştirmeleri" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.10 'Breezy Badger' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.04 Güvenlik Güncelleştirmeleri" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.10 'Breezy Badger' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Topluluk tarafından bakılan" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "Kısıtlı yazılımlar" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Canonical Açık Kaynak yazılımı destekledi" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Topluluk tarafından bakılan (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Topluluk tarafından bakılan Açık Kaynak Kodlu yazılımlar" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "Özgür olmayan sürücüler" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "Aygıtlar için kapalı kaynak sürücüler" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "Kısıtlı yazılımlar (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "Yazılım telif haklarıyla veya yasal sorunlar sebebiyle kısıtlanmıştır" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "Önemli güvenlik güncelleştirmeleri" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "Önerilen güncellemeler" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Teklif edilmiş güncellemeler" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Geritaşınmış (backported) güncellemeler" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger' Cdrom'u" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 Güvenlik Güncelleştirmeleri" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 Güvenlik Güncelleştirmeleri" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 Geritaşınmış Yazılımlar (Backports)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog' Cdrom'u" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Resmi olarak desteklenenler" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 Güvenlik Güncelleştirmeleri" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04 Güncelleştirmeleri" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 Geritaşınmış Yazılımlar (Backports)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Topluluk tarafından bakılan (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Özgür olmayan (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog' Cdrom'u" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "Artık resmi olarak desteklenmiyor" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Sınırlı telif hakkı" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 Güvenlik Güncelleştirmeleri" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 Güncelleştirmeleri" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 Geritaşınmış Yazılımlar (Backports)" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "Teklif edilmiş güncellemeler" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Önemli güvenlik güncelleştirmeleri" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (test)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (kararsız)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "Özgür Olmayan Bağımlılığı Bulunan DFSG Uyumlu Yazılım" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "DFSG Uyumlu Olmayan Yazılım" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "%s sunucusu" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "Ana sunucu" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "Özel sunucular" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Ayrıntılar" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "Değişiklikler listesi erişilebilir değil" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Değişiklik listesini indirme başarısız oldu. \n" +"Lütfen İnternet bağlantınızı kontrol edin." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "'%s' yüklenemiyor" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Gerekli bir paketin kaldırılması gerekmekte" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/uk.po b/po/uk.po new file mode 100644 index 0000000..9ed1185 --- /dev/null +++ b/po/uk.po @@ -0,0 +1,635 @@ +# translation of uk(5).po to Ukrainian +# Maxim Dziumanenko , 2005. +# Vadim Abramchuck , 2006. +# Ukrainian translation of update-manager. +# Copyright (C) 2005, 2006 Free Software Foundation, Inc. +msgid "" +msgstr "" +"Project-Id-Version: uk(5)\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:15+0000\n" +"Last-Translator: Vadim Abramchuck \n" +"Language-Team: Ukrainian \n" +"Language: uk\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" +"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" +"X-Generator: KBabel 1.11.2\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Підтримується спільнотою (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Підтримується спільнотою (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Підтримується спільнотою (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Підтримується спільнотою (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Оновлення через Інтернет" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "Офіційно підтримуються" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Підтримується спільнотою (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Не-вільний (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Обмежені авторські права" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Оновлення через Інтернет" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian \"Etch\" (тестовий)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (нестабільний)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "Завантажується файл %li of %li at %s/s" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "Завантажується файл %li of %li at %s/s" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "Деталі" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"не вдається завантажити зміни. Перевірте чи активне з'єднання з Інтернет." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Не можливо встановити '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Це призведе до видалення !essential! пакунку системи" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/vi.po b/po/vi.po new file mode 100644 index 0000000..31ac60c --- /dev/null +++ b/po/vi.po @@ -0,0 +1,683 @@ +# Vietnamese translation for Update Manager. +# Copyright © 2005 Gnome i18n Project for Vietnamese. +# Clytie Siddall , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager Gnome HEAD\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:17+0000\n" +"Last-Translator: Tran The Trung \n" +"Language-Team: Vietnamese \n" +"Language: vi\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=utf-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" +"X-Generator: LocFactoryEditor 1.2.2\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Bản cập nhật bảo mặt Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Đĩa CD chứa « Breezy Badger » của Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Đĩa CD chứa « Hoary Hedgehog » của Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Đĩa CD chứa « Hoary Hedgehog » của Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Đĩa CD chứa « Hoary Hedgehog » của Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Đĩa CD chứa « Hoary Hedgehog » của Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Đĩa CD chứa « Hoary Hedgehog » của Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Đĩa CD chứa « Hoary Hedgehog » của Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Bản cập nhật bảo mặt Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Đĩa CD chứa « Breezy Badger » của Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Bản cập nhật bảo mặt Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Đĩa CD chứa « Breezy Badger » của Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +#, fuzzy +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Bản cập nhật Ubuntu 5.10" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "Do cộng đồng bảo quản (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +#, fuzzy +msgid "Restricted software" +msgstr "Phần mềm đã đóng góp" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +#, fuzzy +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +#, fuzzy +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Bản cập nhật Ubuntu 5.04" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "Do cộng đồng bảo quản (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "Do cộng đồng bảo quản (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "Do cộng đồng bảo quản (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +#, fuzzy +msgid "Non-free drivers" +msgstr "Không tự do (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +#, fuzzy +msgid "Restricted software (Multiverse)" +msgstr "Không tự do (Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +#, fuzzy +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Bản cập nhật Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +#, fuzzy +msgid "Important security updates" +msgstr "Bản cập nhật bảo mặt Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "Đang cài đặt bản cập nhật..." + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "Đang cài đặt bản cập nhật..." + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +#, fuzzy +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Đĩa CD chứa « Breezy Badger » của Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +#, fuzzy +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Đĩa CD chứa « Breezy Badger » của Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Bản cập nhật bảo mặt Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Bản cập nhật Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +#, fuzzy +msgid "Ubuntu 5.10 Backports" +msgstr "Bản cập nhật Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +#, fuzzy +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Đĩa CD chứa « Hoary Hedgehog » của Ubuntu 5.04" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +#, fuzzy +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Đĩa CD chứa « Hoary Hedgehog » của Ubuntu 5.04" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +#, fuzzy +msgid "Officially supported" +msgstr "Được hỗ trợ một cách chính thức" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +#, fuzzy +msgid "Ubuntu 5.04 Security Updates" +msgstr "Bản cập nhật bảo mặt Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +#, fuzzy +msgid "Ubuntu 5.04 Updates" +msgstr "Bản cập nhật Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +#, fuzzy +msgid "Ubuntu 5.04 Backports" +msgstr "Bản cập nhật Ubuntu 5.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +#, fuzzy +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "Do cộng đồng bảo quản (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "Không tự do (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +#, fuzzy +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Đĩa CD chứa « Warty Warthog » của Ubuntu 4.10" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +#, fuzzy +msgid "No longer officially supported" +msgstr "Được hỗ trợ một cách chính thức" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "Bản quyền bị giới hạn" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Bản cập nhật bảo mặt Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Bản cập nhật Ubuntu 4.10" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +#, fuzzy +msgid "Ubuntu 4.10 Backports" +msgstr "Bản cập nhật Ubuntu 5.10" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 « Sarge »" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 « Sarge »" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 « Sarge »" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 « Sarge »" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 « Sarge »" + +#. Description +#: ../data/templates/Debian.info.in:119 +#, fuzzy +msgid "Proposed updates" +msgstr "Đang cài đặt bản cập nhật..." + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "Bản cập nhật bảo mặt Ubuntu 5.10" + +#. Description +#: ../data/templates/Debian.info.in:133 +#, fuzzy +msgid "Debian current stable release" +msgstr "Bất định Debian « Sid »" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Thử ra Debian" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Không Mỹ Debian (Bất định)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +#, fuzzy +msgid "Details" +msgstr "Chi tiết" + +#: ../apt/progress/gtk2.py:428 +#, fuzzy +msgid "Starting..." +msgstr "Thiết lập" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +#, fuzzy +msgid "The list of changes is not available" +msgstr "Có một bản phát hành Ubuntu mới công bố." + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" +"Không tải thay đổi về được. Bạn hãy kiểm tra có kết nối đến Mạng hoạt động " +"chưa." + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "Không thể cài đặt '%s'" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "Một gói quan trọng cần phải bị gỡ bỏ" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/zh_CN.po b/po/zh_CN.po new file mode 100644 index 0000000..004245c --- /dev/null +++ b/po/zh_CN.po @@ -0,0 +1,656 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER +# This file is distributed under the same license as the PACKAGE package. +# Funda Wang , 2005. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager HEAD\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2009-09-06 03:14+0000\n" +"Last-Translator: Feng Chao \n" +"Language-Team: zh_CN \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +#| msgid "Ubuntu 7.04 'Feisty Fawn'" +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 7.04‘(Feisty Fawn)’" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +#| msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "已插入 Ubuntu 7.04 'Feisty Fawn' 光盘的光驱" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +#| msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 6.10 'Edgy Eft' 光盘" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Warty Warthog'光盘" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Warty Warthog'光盘" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +#| msgid "Ubuntu 8.04 'Hardy Heron'" +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 8.04‘Hardy Heron’" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +#| msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "已插入 Ubuntu 8.04 'Hardy Heron' 光盘的光驱" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Warty Warthog'光盘" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Warty Warthog'光盘" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +#| msgid "Ubuntu 8.04 'Hardy Heron'" +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 8.04‘Hardy Heron’" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +#| msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "已插入 Ubuntu 8.04 'Hardy Heron' 光盘的光驱" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 8.04‘Hardy Heron’" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "已插入 Ubuntu 8.04 'Hardy Heron' 光盘的光驱" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10‘Gutsy Gibbon’" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 7.10‘Gutsy Gibbon’光盘" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 7.04‘(Feisty Fawn)’" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "已插入 Ubuntu 7.04 'Feisty Fawn' 光盘的光驱" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +msgid "Community-maintained" +msgstr "社区维护" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "受限软件" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft' 光盘" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +#| msgid "Canonical-supported Open Source software" +msgid "Canonical-supported free and open-source software" +msgstr "Canonical 支持的开源软件" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +msgid "Community-maintained (universe)" +msgstr "社区维护 (universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +#| msgid "Community-maintained Open Source software" +msgid "Community-maintained free and open-source software" +msgstr "社区维护的开源软件" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "非开源或私有驱动" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "设备的专有驱动" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "受限软件(Multiverse)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "有版权和合法性问题的的软件" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake' 光盘" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "重要安全更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "推荐更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +msgid "Pre-released updates" +msgstr "提前释放出的更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +msgid "Unsupported updates" +msgstr "不支持的更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger' 光盘" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10 安全更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10 更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "Ubuntu 5.10 移植" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'光盘" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "官方支持" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04 安全更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.10 更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "Ubuntu 5.04 Backports" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +msgid "Community-maintained (Universe)" +msgstr "社区维护 (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "非自由" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'光盘" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "官方不再支持" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "版权受限" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10 安全更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10 更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "Ubuntu 4.10 Backports" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 \"Sarge\"" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "建议更新" + +#. Description +#: ../data/templates/Debian.info.in:126 +msgid "Security updates" +msgstr "安全更新" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "当前稳定的 Debian 发布" + +#. Description +#: ../data/templates/Debian.info.in:146 +msgid "Debian testing" +msgstr "Debian testing" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian \"Sid\" (非稳定)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "带有非自由依赖关系的DFSG兼容软件" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "非DFSG兼容软件" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "%s 的服务器" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "主服务器" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "自定义服务器" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +msgid "The list of changes is not available" +msgstr "" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "" + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, python-format +msgid "Cannot install '%s'" +msgstr "" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +msgid "An essential package would be removed" +msgstr "" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/zh_HK.po b/po/zh_HK.po new file mode 100644 index 0000000..08190a3 --- /dev/null +++ b/po/zh_HK.po @@ -0,0 +1,633 @@ +# Chinese (Hong Kong) translation of update-manager. +# Copyright (C) 2005, 2006 Free Software Foundation, Inc. +# Abel Cheung , 2005, 2006. +# +msgid "" +msgstr "" +"Project-Id-Version: update-manager 0.42.2\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:15+0000\n" +"Last-Translator: Abel Cheung \n" +"Language-Team: Chinese (Hong Kong) \n" +"Language: zh_HK\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0;\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "協力維護軟件 (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "協力維護軟件 (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "協力維護軟件 (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "協力維護軟件 (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "發行通告" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "網絡更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "正式支援" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "協力維護軟件 (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "非自由軟件 (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "版權受限" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1「Sarge」" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1「Sarge」" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1「Sarge」" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1「Sarge」" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1「Sarge」" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "網絡更新" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian 「Etch」(測試版)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian 「Sid」(不穩定版)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "符合 DFSG 的軟件,但依賴於非自由軟件" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "和 DFSG 不相容的軟件" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "正在下載檔案 %li/%li,下載速度為 %s/秒" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "正在下載檔案 %li/%li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "詳細資料" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +#, fuzzy +msgid "The list of changes is not available" +msgstr "修改紀錄不存在,請稍後再試。" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "無法下載更改紀錄。請檢查網絡連線是否正常。" + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "無法安裝「%s」" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "準備移除 %s 個套件。" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/po/zh_TW.po b/po/zh_TW.po new file mode 100644 index 0000000..8fb1060 --- /dev/null +++ b/po/zh_TW.po @@ -0,0 +1,653 @@ +msgid "" +msgstr "" +"Project-Id-Version: update-manager 0.41.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-06-25 14:31+0200\n" +"PO-Revision-Date: 2006-10-16 04:15+0000\n" +"Last-Translator: SOC Ho \n" +"Language-Team: Chinese (Taiwan) \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=1; plural=0\n" + +#. ChangelogURI +#: ../data/templates/Ubuntu.info.in.h:4 +#, no-c-format +msgid "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://changelogs.ubuntu.com/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Ubuntu.info.in:151 +#, fuzzy +msgid "Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.04安全性更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:158 +#, fuzzy +msgid "Cdrom with Ubuntu 12.04 'Precise Pangolin'" +msgstr "Ubuntu 5.10 'Breezy Badger'的光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:269 +#, fuzzy +msgid "Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:276 +#, fuzzy +msgid "Cdrom with Ubuntu 11.10 'Oneiric Ocelot'" +msgstr "含Ubuntu 4.10 'Warty Warthog'之光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:388 +#, fuzzy +#| msgid "Ubuntu 4.10 'Warty Warthog'" +msgid "Ubuntu 11.04 'Natty Narwhal'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:395 +#, fuzzy +#| msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgid "Cdrom with Ubuntu 11.04 'Natty Narwhal'" +msgstr "含Ubuntu 4.10 'Warty Warthog'之光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:486 +#, fuzzy +msgid "Ubuntu 10.10 'Maverick Meerkat'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:506 +#, fuzzy +msgid "Cdrom with Ubuntu 10.10 'Maverick Meerkat'" +msgstr "含Ubuntu 4.10 'Warty Warthog'之光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:518 +msgid "Canonical Partners" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:520 +msgid "Software packaged by Canonical for their partners" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:521 +msgid "This software is not part of Ubuntu." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:528 +msgid "Independent" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:530 +msgid "Provided by third-party software developers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:531 +msgid "Software offered by third party developers." +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:569 +#, fuzzy +msgid "Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:589 +#, fuzzy +msgid "Cdrom with Ubuntu 10.04 'Lucid Lynx'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'的光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:632 +#, fuzzy +msgid "Ubuntu 9.10 'Karmic Koala'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:652 +#, fuzzy +msgid "Cdrom with Ubuntu 9.10 'Karmic Koala'" +msgstr "含Ubuntu 4.10 'Warty Warthog'之光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:695 +#, fuzzy +msgid "Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:714 +#, fuzzy +msgid "Cdrom with Ubuntu 9.04 'Jaunty Jackalope'" +msgstr "含Ubuntu 4.10 'Warty Warthog'之光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:757 +#, fuzzy +msgid "Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:777 +#, fuzzy +msgid "Cdrom with Ubuntu 8.10 'Intrepid Ibex'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'的光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:821 +#, fuzzy +msgid "Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:841 +#, fuzzy +msgid "Cdrom with Ubuntu 8.04 'Hardy Heron'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'的光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:886 +#, fuzzy +msgid "Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.04安全性更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:905 +#, fuzzy +msgid "Cdrom with Ubuntu 7.10 'Gutsy Gibbon'" +msgstr "Ubuntu 5.10 'Breezy Badger'的光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:950 +#, fuzzy +msgid "Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.04安全性更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:969 +#, fuzzy +msgid "Cdrom with Ubuntu 7.04 'Feisty Fawn'" +msgstr "Ubuntu 5.10 'Breezy Badger'的光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:1011 +msgid "Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1016 +#, fuzzy +msgid "Community-maintained" +msgstr "協力維護軟體 (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1022 +msgid "Restricted software" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1030 +msgid "Cdrom with Ubuntu 6.10 'Edgy Eft'" +msgstr "Ubuntu 6.10 'Edgy Eft'的光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:1072 +msgid "Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "Ubuntu 6.06 LTS 'Dapper Drake'" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1075 +#, fuzzy +msgid "Canonical-supported free and open-source software" +msgstr "協力維護軟體 (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1077 +#, fuzzy +msgid "Community-maintained (universe)" +msgstr "協力維護軟體 (Universe)" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1078 +#, fuzzy +msgid "Community-maintained free and open-source software" +msgstr "協力維護軟體 (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1080 +msgid "Non-free drivers" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1081 +msgid "Proprietary drivers for devices" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1083 +msgid "Restricted software (Multiverse)" +msgstr "" + +#. CompDescriptionLong +#: ../data/templates/Ubuntu.info.in:1084 +msgid "Software restricted by copyright or legal issues" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1091 +msgid "Cdrom with Ubuntu 6.06 LTS 'Dapper Drake'" +msgstr "含Ubuntu 6.06 LTS 'Dapper Drake'之光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:1107 +msgid "Important security updates" +msgstr "重要的安全更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1112 +msgid "Recommended updates" +msgstr "建議的安全更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1117 +#, fuzzy +msgid "Pre-released updates" +msgstr "建議的安全更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1122 +#, fuzzy +msgid "Unsupported updates" +msgstr "重要的安全更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1133 +msgid "Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1148 +msgid "Cdrom with Ubuntu 5.10 'Breezy Badger'" +msgstr "Ubuntu 5.10 'Breezy Badger'的光碟" + +#. Description +#: ../data/templates/Ubuntu.info.in:1164 +msgid "Ubuntu 5.10 Security Updates" +msgstr "Ubuntu 5.10安全性更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1169 +msgid "Ubuntu 5.10 Updates" +msgstr "Ubuntu 5.10更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1174 +msgid "Ubuntu 5.10 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1185 +msgid "Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'" + +#. Description +#: ../data/templates/Ubuntu.info.in:1200 +msgid "Cdrom with Ubuntu 5.04 'Hoary Hedgehog'" +msgstr "Ubuntu 5.04 'Hoary Hedgehog'的光碟" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1203 ../data/templates/Debian.info.in:174 +msgid "Officially supported" +msgstr "官方支援" + +#. Description +#: ../data/templates/Ubuntu.info.in:1216 +msgid "Ubuntu 5.04 Security Updates" +msgstr "Ubuntu 5.04安全性更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1221 +msgid "Ubuntu 5.04 Updates" +msgstr "Ubuntu 5.04更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1226 +msgid "Ubuntu 5.04 Backports" +msgstr "" + +#. Description +#: ../data/templates/Ubuntu.info.in:1232 +msgid "Ubuntu 4.10 'Warty Warthog'" +msgstr "Ubuntu 4.10 'Warty Warthog'" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1238 +#, fuzzy +msgid "Community-maintained (Universe)" +msgstr "協力維護軟體 (Universe)" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1240 +msgid "Non-free (Multiverse)" +msgstr "非自由軟體 (Multiverse)" + +#. Description +#: ../data/templates/Ubuntu.info.in:1247 +msgid "Cdrom with Ubuntu 4.10 'Warty Warthog'" +msgstr "含Ubuntu 4.10 'Warty Warthog'之光碟" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1250 +msgid "No longer officially supported" +msgstr "" + +#. CompDescription +#: ../data/templates/Ubuntu.info.in:1252 +msgid "Restricted copyright" +msgstr "版權受限制" + +#. Description +#: ../data/templates/Ubuntu.info.in:1259 +msgid "Ubuntu 4.10 Security Updates" +msgstr "Ubuntu 4.10安全性更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1264 +msgid "Ubuntu 4.10 Updates" +msgstr "Ubuntu 4.10更新" + +#. Description +#: ../data/templates/Ubuntu.info.in:1269 +msgid "Ubuntu 4.10 Backports" +msgstr "" + +#. ChangelogURI +#: ../data/templates/Debian.info.in.h:4 +#, no-c-format +msgid "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" +msgstr "http://packages.debian.org/changelogs/pool/%s/%s/%s/%s_%s/changelog" + +#. Description +#: ../data/templates/Debian.info.in:8 +#, fuzzy +msgid "Debian 7 'Wheezy' " +msgstr "Debian 3.1 “Sarge”" + +#. Description +#: ../data/templates/Debian.info.in:33 +#, fuzzy +msgid "Debian 6.0 'Squeeze' " +msgstr "Debian 3.1 “Sarge”" + +#. Description +#: ../data/templates/Debian.info.in:58 +#, fuzzy +msgid "Debian 5.0 'Lenny' " +msgstr "Debian 3.1 “Sarge”" + +#. Description +#: ../data/templates/Debian.info.in:83 +#, fuzzy +msgid "Debian 4.0 'Etch'" +msgstr "Debian 3.1 “Sarge”" + +#. Description +#: ../data/templates/Debian.info.in:108 +#, fuzzy +msgid "Debian 3.1 'Sarge'" +msgstr "Debian 3.1 “Sarge”" + +#. Description +#: ../data/templates/Debian.info.in:119 +msgid "Proposed updates" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:126 +#, fuzzy +msgid "Security updates" +msgstr "重要的安全更新" + +#. Description +#: ../data/templates/Debian.info.in:133 +msgid "Debian current stable release" +msgstr "" + +#. Description +#: ../data/templates/Debian.info.in:146 +#, fuzzy +msgid "Debian testing" +msgstr "Debian “Etch”(測試版)" + +#. Description +#: ../data/templates/Debian.info.in:172 +#, fuzzy +msgid "Debian 'Sid' (unstable)" +msgstr "Debian “Sid”(不穩定版)" + +#. CompDescription +#: ../data/templates/Debian.info.in:176 +msgid "DFSG-compatible Software with Non-Free Dependencies" +msgstr "符合 DFSG 的軟體,但有依賴於非自由軟體" + +#. CompDescription +#: ../data/templates/Debian.info.in:178 +msgid "Non-DFSG-compatible Software" +msgstr "不符合 DFSG 的軟體" + +#. TRANSLATORS: %s is a country +#: ../aptsources/distro.py:206 ../aptsources/distro.py:436 +#, python-format +msgid "Server for %s" +msgstr "位於%s的伺服器" + +#. More than one server is used. Since we don't handle this case +#. in the user interface we set "custom servers" to true and +#. append a list of all used servers +#: ../aptsources/distro.py:224 ../aptsources/distro.py:230 +#: ../aptsources/distro.py:246 +msgid "Main server" +msgstr "主要伺服器" + +#: ../aptsources/distro.py:250 +msgid "Custom servers" +msgstr "個人伺服器" + +#: ../apt/progress/gtk2.py:258 ../apt/progress/gtk2.py:314 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li with %(speed)s/s" +msgstr "正在下載檔案 %li/%li,下載速度為 %s/秒" + +#: ../apt/progress/gtk2.py:264 ../apt/progress/gtk2.py:320 +#, fuzzy, python-format +msgid "Downloading file %(current)li of %(total)li" +msgstr "正在下載檔案 %li/%li" + +#. Setup some child widgets +#: ../apt/progress/gtk2.py:340 +msgid "Details" +msgstr "詳細資料" + +#: ../apt/progress/gtk2.py:428 +msgid "Starting..." +msgstr "" + +#: ../apt/progress/gtk2.py:434 +msgid "Complete" +msgstr "" + +#: ../apt/package.py:359 +#, python-format +msgid "Invalid unicode in description for '%s' (%s). Please report." +msgstr "" + +#: ../apt/package.py:1088 ../apt/package.py:1194 +#, fuzzy +msgid "The list of changes is not available" +msgstr "修改紀錄不存在,請稍後再試。" + +#: ../apt/package.py:1200 +#, python-format +msgid "" +"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." +msgstr "" + +#: ../apt/package.py:1207 +#, fuzzy +msgid "" +"Failed to download the list of changes. \n" +"Please check your Internet connection." +msgstr "無法下載更動列表。請檢查網路連線是否正常。" + +#: ../apt/debfile.py:82 +#, python-format +msgid "List of files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:93 +#, python-format +msgid "List of control files for '%s' could not be read" +msgstr "" + +#: ../apt/debfile.py:211 +#, python-format +msgid "Dependency is not satisfiable: %s\n" +msgstr "" + +#: ../apt/debfile.py:232 +#, python-format +msgid "Conflicts with the installed package '%s'" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that breaks, the second the dependency that makes it break, the third the relation (e.g. >=) and the latest the version for the releation +#: ../apt/debfile.py:373 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' dependency %(depname)s " +"(%(deprelation)s %(depversion)s)" +msgstr "" + +#. TRANSLATORS: the first '%s' is the package that conflicts, the second the packagename that it conflicts with (so the name of the deb the user tries to install), the third is the relation (e.g. >=) and the last is the version for the relation +#: ../apt/debfile.py:389 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' conflict: %(targetpkg)s (%(comptype)s " +"%(targetver)s)" +msgstr "" + +#: ../apt/debfile.py:399 +#, python-format +msgid "" +"Breaks existing package '%(pkgname)s' that conflict: '%(targetpkg)s'. But " +"the '%(debfile)s' provides it via: '%(provides)s'" +msgstr "" + +#: ../apt/debfile.py:447 +msgid "No Architecture field in the package" +msgstr "" + +#: ../apt/debfile.py:457 +#, python-format +msgid "Wrong architecture '%s'" +msgstr "" + +#. the deb is older than the installed +#: ../apt/debfile.py:464 +msgid "A later version is already installed" +msgstr "" + +#: ../apt/debfile.py:489 +msgid "Failed to satisfy all dependencies (broken cache)" +msgstr "" + +#: ../apt/debfile.py:519 +#, fuzzy, python-format +msgid "Cannot install '%s'" +msgstr "無法安裝‘%s’" + +#: ../apt/debfile.py:593 +msgid "" +"Automatically decompressed:\n" +"\n" +msgstr "" + +#: ../apt/debfile.py:599 +msgid "Automatically converted to printable ascii:\n" +msgstr "" + +#: ../apt/debfile.py:689 +#, python-format +msgid "Install Build-Dependencies for source package '%s' that builds %s\n" +msgstr "" + +#: ../apt/debfile.py:700 +#, fuzzy +msgid "An essential package would be removed" +msgstr "將會移除的核心套件" + +#: ../apt/progress/text.py:82 +#, python-format +msgid "%c%s... Done" +msgstr "" + +#: ../apt/progress/text.py:122 +msgid "Hit " +msgstr "" + +#: ../apt/progress/text.py:131 +msgid "Ign " +msgstr "" + +#: ../apt/progress/text.py:133 +msgid "Err " +msgstr "" + +#: ../apt/progress/text.py:144 +msgid "Get:" +msgstr "" + +#: ../apt/progress/text.py:203 +msgid " [Working]" +msgstr "" + +#: ../apt/progress/text.py:214 +#, python-format +msgid "" +"Media change: please insert the disc labeled\n" +" '%s'\n" +"in the drive '%s' and press enter\n" +msgstr "" + +#. Trick for getting a translation from apt +#: ../apt/progress/text.py:223 +#, python-format +msgid "Fetched %sB in %s (%sB/s)\n" +msgstr "" + +#: ../apt/progress/text.py:239 +msgid "Please provide a name for this Disc, such as 'Debian 2.1r1 Disk 1'" +msgstr "" + +#: ../apt/progress/text.py:255 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: ../apt/cache.py:157 +msgid "Building data structures" +msgstr "" diff --git a/pre-build.sh b/pre-build.sh new file mode 100755 index 0000000..930be76 --- /dev/null +++ b/pre-build.sh @@ -0,0 +1,18 @@ +#!/bin/sh +set -e + +echo "Running pycodestyle test" +black --check . || [ "$IGNORE_BLACK" ] || \ + [ "$IGNORE_PYCODESTYLE" ] || [ "$IGNORE_PEP8" ] + +dpkg-checkbuilddeps -d 'python3-debian, python3-feedparser' + +echo "updating Ubuntu mirror list from launchpad" +if [ -n "$https_proxy" ]; then + echo "disabling https_proxy as Python's urllib doesn't support it; see #94130" + unset https_proxy +fi +utils/get_ubuntu_mirrors_from_lp.py > data/templates/Ubuntu.mirrors + +echo "updating Debian mirror list" +utils/get_debian_mirrors.py > data/templates/Debian.mirrors diff --git a/python/acquire-item.cc b/python/acquire-item.cc new file mode 100644 index 0000000..af79fd9 --- /dev/null +++ b/python/acquire-item.cc @@ -0,0 +1,356 @@ +/* + * acquire-item.cc - Wrapper around pkgAcquire::Item and pkgAcqFile. + * + * Copyright 2004-2009 Canonical Ltd. + * Copyright 2009 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "generic.h" +#include "apt_pkgmodule.h" + +#include +#include + +using namespace std; + +inline pkgAcquire::Item *acquireitem_tocpp(PyObject *self) +{ + pkgAcquire::Item *itm = GetCpp(self); + if (itm == 0) + PyErr_SetString(PyExc_ValueError, "Acquire() has been shut down or " + "the AcquireFile() object has been deallocated."); + return itm; +} + +static PyObject *acquireitem_get_complete(PyObject *self, void *closure) +{ + pkgAcquire::Item *item = acquireitem_tocpp(self); + return item ? PyBool_FromLong(item->Complete) : 0; +} + +static PyObject *acquireitem_get_desc_uri(PyObject *self, void *closure) +{ + pkgAcquire::Item *item = acquireitem_tocpp(self); + return item ? CppPyString(item->DescURI()) : 0; +} + +static PyObject *acquireitem_get_destfile(PyObject *self, void *closure) +{ + pkgAcquire::Item *item = acquireitem_tocpp(self); + return item ? CppPyPath(item->DestFile) : 0; +} + + +static PyObject *acquireitem_get_error_text(PyObject *self, void *closure) +{ + pkgAcquire::Item *item = acquireitem_tocpp(self); + return item ? CppPyString(item->ErrorText) : 0; +} + +static PyObject *acquireitem_get_filesize(PyObject *self, void *closure) +{ + pkgAcquire::Item *item = acquireitem_tocpp(self); + return item ? MkPyNumber(item->FileSize) : 0; +} + +static PyObject *acquireitem_get_id(PyObject *self, void *closure) +{ + pkgAcquire::Item *item = acquireitem_tocpp(self); + return item ? MkPyNumber(item->ID) : 0; +} + +static PyObject *acquireitem_get_active_subprocess(PyObject *self, void *closure) +{ + pkgAcquire::Item *item = acquireitem_tocpp(self); +#if APT_PKG_MAJOR >= 5 + return item ? Py_BuildValue("s", item->ActiveSubprocess.c_str()) : 0; +#else + return item ? Py_BuildValue("s", item->Mode) : 0; +#endif +} + +static PyObject *acquireitem_get_mode(PyObject *self, void *closure) +{ + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "AcquireItem.mode is deprecated, use AcquireItem.active_subprocess instead.", 1) == -1) + return NULL; + return acquireitem_get_active_subprocess(self, closure); +} + +static PyObject *acquireitem_get_is_trusted(PyObject *self, void *closure) +{ + pkgAcquire::Item *item = acquireitem_tocpp(self); + return item ? PyBool_FromLong(item->IsTrusted()) : 0; +} + +static PyObject *acquireitem_get_local(PyObject *self, void *closure) +{ + pkgAcquire::Item *item = acquireitem_tocpp(self); + return item ? PyBool_FromLong(item->Local) : 0; +} + +static PyObject *acquireitem_get_partialsize(PyObject *self, void *closure) +{ + pkgAcquire::Item *item = acquireitem_tocpp(self); + return item ? MkPyNumber(item->PartialSize) : 0; +} + +static PyObject *acquireitem_get_status(PyObject *self, void *closure) +{ + pkgAcquire::Item *item = acquireitem_tocpp(self); + return item ? MkPyNumber(item->Status) : 0; +} + +static int acquireitem_set_id(PyObject *self, PyObject *value, void *closure) +{ + pkgAcquire::Item *Itm = acquireitem_tocpp(self); + if (Itm == 0) + return -1; + if (PyLong_Check(value)) { + Itm->ID = PyLong_AsUnsignedLong(value); + } + else if (PyInt_Check(value)) { + Itm->ID = PyInt_AsLong(value); + } + else { + PyErr_SetString(PyExc_TypeError, "value must be integer."); + return -1; + } + return 0; +} + + +static PyGetSetDef acquireitem_getset[] = { + {"complete",acquireitem_get_complete,0, + "A boolean value determining whether the item has been fetched\n" + "completely"}, + {"desc_uri",acquireitem_get_desc_uri,NULL, + "A string describing the URI from which the item is acquired."}, + {"destfile",acquireitem_get_destfile,NULL, + "The path to the file where the item will be stored."}, + {"error_text",acquireitem_get_error_text,NULL, + "If an error occurred, a string describing the error; empty string\n" + "otherwise."}, + {"filesize",acquireitem_get_filesize,NULL, + "The size of the file (number of bytes). If unknown, it is set to 0."}, + {"id",acquireitem_get_id,acquireitem_set_id, + "The ID of the item. An integer which can be set by progress classes."}, + {"mode",acquireitem_get_mode,NULL, + "Old name for active_subprocess"}, + {"active_subprocess",acquireitem_get_active_subprocess,NULL, + "The name of the active subprocess (for instance, 'gzip', 'rred' or 'gpgv')."}, + {"is_trusted",acquireitem_get_is_trusted,NULL, + "Whether the item is trusted or not. Only True for packages\n" + "which come from a repository signed with one of the keys in\n" + "APT's keyring."}, + {"local",acquireitem_get_local,NULL, + "Whether we are fetching a local item (copy:/) or not."}, + {"partialsize",acquireitem_get_partialsize,NULL, + "The amount of data which has already been fetched (number of bytes)."}, + {"status",acquireitem_get_status,NULL, + "An integer representing the item's status which can be compared\n" + "against one of the STAT_* constants defined in this class."}, + {} +}; + +static PyObject *acquireitem_repr(PyObject *Self) +{ + pkgAcquire::Item *Itm = acquireitem_tocpp(Self); + if (Itm == 0) + return 0; + + string repr; + strprintf(repr, "<%s object:" + "Status: %i Complete: %i Local: %i IsTrusted: %i " + "FileSize: %llu DestFile:'%s' " + "DescURI: '%s' ID:%lu ErrorText: '%s'>", + Self->ob_type->tp_name, + Itm->Status, Itm->Complete, Itm->Local, Itm->IsTrusted(), + Itm->FileSize, Itm->DestFile.c_str(), Itm->DescURI().c_str(), + Itm->ID,Itm->ErrorText.c_str()); + // Use CppPyPath here, the string may contain a path, so we should + // decode it like one. + return CppPyPath(repr); +} + +static void acquireitem_dealloc(PyObject *self) +{ + CppDeallocPtr(self); +} + +static const char *acquireitem_doc = + "Represent a single item to be fetched by an Acquire object.\n\n" + "It is not possible to construct instances of this class directly.\n" + "Prospective users should construct instances of a subclass such as\n" + "AcquireFile instead. It is not possible to create subclasses on the\n" + "Python level, only on the C++ level."; +PyTypeObject PyAcquireItem_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.AcquireItem", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + acquireitem_dealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + acquireitem_repr, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | + Py_TPFLAGS_HAVE_GC, // tp_flags + acquireitem_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + acquireitem_getset, // tp_getset +}; + +static PyObject *acquirefile_new(PyTypeObject *type, PyObject *Args, PyObject * kwds) +{ + PyObject *pyfetcher; + PyObject *pyhashes = nullptr; + HashStringList hashes; + const char *uri, *descr, *shortDescr; + PyApt_Filename destDir, destFile; + unsigned long long size = 0; + uri = descr = shortDescr = destDir = destFile = ""; + + char *kwlist[] = {"owner", "uri", "hash", "size", "descr", "short_descr", + "destdir", "destfile", NULL + }; +#if PY_MAJOR_VERSION >= 3 + const char *fmt = "O!s|OKssO&O&"; +#else + // no "$" support to indicate that the remaining args are keyword only + // in py2.x :/ + const char *fmt = "O!s|OKssO&O&"; +#endif + if (PyArg_ParseTupleAndKeywords(Args, kwds, fmt, kwlist, + &PyAcquire_Type, &pyfetcher, &uri, + &pyhashes, + &size, &descr, &shortDescr, + PyApt_Filename::Converter, &destDir, + PyApt_Filename::Converter, &destFile) == 0) + return 0; + + if (pyhashes == nullptr) + ; + else if (PyString_Check(pyhashes)) + hashes = HashStringList(PyString_AsString(pyhashes)); + else if (PyObject_TypeCheck(pyhashes, &PyHashStringList_Type)) + hashes = GetCpp (pyhashes); + else + return PyErr_SetString(PyExc_TypeError, "'hash' value must be an apt_pkg.HashStringList or a string"), nullptr; + + pkgAcquire *fetcher = GetCpp(pyfetcher); + pkgAcqFile *af = new pkgAcqFile(fetcher, // owner + uri, // uri + hashes, // hash + size, // size + descr, // descr + shortDescr, + destDir, + destFile); // short-desc + CppPyObject *AcqFileObj = CppPyObject_NEW(pyfetcher, type); + AcqFileObj->Object = af; + return AcqFileObj; +} + + +static char *acquirefile_doc = + "AcquireFile(owner, uri[, hash: Union[apt_pkg.HashStringList, str], size, descr, short_descr, destdir," + "destfile])\n\n" + "Represent a file to be fetched. The parameter 'owner' points to\n" + "an apt_pkg.Acquire object and the parameter 'uri' to the source\n" + "location. Normally, the file will be stored in the current directory\n" + "using the file name given in the URI. This directory can be changed\n" + "by passing the name of a directory to the 'destdir' parameter. It is\n" + "also possible to set a path to a file using the 'destfile' parameter,\n" + "but both cannot be specified together.\n" + "\n" + "The parameters 'short_descr' and 'descr' can be used to specify\n" + "a short description and a longer description for the item. This\n" + "information is used by progress classes to refer to the item and\n" + "should be short, for example, package name as 'short_descr' and\n" + "and something like 'http://localhost sid/main python-apt 0.7.94.2'\n" + "as 'descr'." + "\n" + "The parameters 'hash' and 'size' are used to verify the resulting\n" + "file. The parameter 'size' is also to calculate the total amount\n" + "of data to be fetched and is useful for resuming a interrupted\n" + "download.\n\n" + "All parameters can be given by name (i.e. as keyword arguments)."; + +PyTypeObject PyAcquireFile_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.AcquireFile", // tp_name + sizeof(CppPyObject),// tp_basicsize + 0, // tp_itemsize + // Methods + acquireitem_dealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC, + acquirefile_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + 0, // tp_getset + &PyAcquireItem_Type, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + acquirefile_new, // tp_new +}; + diff --git a/python/acquire.cc b/python/acquire.cc new file mode 100644 index 0000000..aab899f --- /dev/null +++ b/python/acquire.cc @@ -0,0 +1,424 @@ +/* acquire.cc - Wrapper for pkgAcquire. + * + * Copyright 2004-2009 Canonical Ltd + * Copyright 2009 Julian Andres Klode + * + * Authors: Michael Vogt + * Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "generic.h" +#include "apt_pkgmodule.h" +#include "progress.h" + +#include +#include + + +static PyObject *acquireworker_get_current_item(PyObject *self, void *closure) +{ + pkgAcquire::Worker *worker = GetCpp(self); + pkgAcquire::ItemDesc *desc = worker->CurrentItem; + if (desc == NULL) { + Py_RETURN_NONE; + } + PyObject *PyAcq = GetOwner(self); + PyObject *PyItem = PyAcquireItem_FromCpp(desc->Owner, false, PyAcq); + PyObject *PyDesc = PyAcquireItemDesc_FromCpp(desc, false, PyItem); + Py_XDECREF(PyItem); + return PyDesc; +} + +static PyObject *acquireworker_get_status(PyObject *self, void *closure) +{ + return CppPyString(GetCpp(self)->Status); +} + +static PyObject *acquireworker_get_current_size(PyObject *self, void *closure) +{ + if (GetCpp(self)->CurrentItem == nullptr) + return 0; + return MkPyNumber(GetCpp(self)->CurrentItem->CurrentSize); +} + +static PyObject *acquireworker_get_total_size(PyObject *self, void *closure) +{ + if (GetCpp(self)->CurrentItem == nullptr) + return 0; + return MkPyNumber(GetCpp(self)->CurrentItem->TotalSize); +} + +static PyObject *acquireworker_get_resumepoint(PyObject *self, void *closure) +{ + if (GetCpp(self)->CurrentItem == nullptr) + return 0; + return MkPyNumber(GetCpp(self)->CurrentItem->ResumePoint); +} + +static PyGetSetDef acquireworker_getset[] = { + {"current_item",acquireworker_get_current_item,0, + "The item currently being fetched, as an apt_pkg.AcquireItemDesc object."}, + {"status",acquireworker_get_status,0, + "The status of the worker, as a string."}, + {"current_size",acquireworker_get_current_size,0, + "The amount of data fetched so far for the current item."}, + {"total_size",acquireworker_get_total_size,0, + "The total size of the item."}, + {"resumepoint",acquireworker_get_resumepoint,0, + "The amount of data which was already available when the download was\n" + "started."}, + {NULL} +}; + +static const char *acquireworker_doc = + "Represent a sub-process responsible for fetching files from\n" + "remote locations. This sub-process uses 'methods' located in\n" + "the directory specified by the configuration option\n" + "Dir::Bin::Methods."; +PyTypeObject PyAcquireWorker_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.AcquireWorker", // tp_name + sizeof(CppPyObject),// tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT| // tp_flags + Py_TPFLAGS_HAVE_GC, + acquireworker_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + acquireworker_getset, // tp_getset +}; + + +static pkgAcquire::ItemDesc* acquireitemdesc_tocpp(PyObject *self) { + pkgAcquire::ItemDesc *item = GetCpp(self); + if (item == NULL) + PyErr_SetString(PyExc_ValueError, "Acquire has been shutdown"); + return item; +} + +static PyObject *acquireitemdesc_get_uri(PyObject *self, void *closure) +{ + pkgAcquire::ItemDesc *item = acquireitemdesc_tocpp(self); + return item ? CppPyString(item->URI) : NULL; +} +static PyObject *acquireitemdesc_get_description(PyObject *self, void *closure) +{ + pkgAcquire::ItemDesc *item = acquireitemdesc_tocpp(self); + return item ? CppPyString(item->Description) : NULL; +} +static PyObject *acquireitemdesc_get_shortdesc(PyObject *self, void *closure) +{ + pkgAcquire::ItemDesc *item = acquireitemdesc_tocpp(self); + return item ? CppPyString(item->ShortDesc) : NULL; +} +static PyObject *acquireitemdesc_get_owner(CppPyObject *self, void *closure) +{ + if (self->Owner != NULL) { + Py_INCREF(self->Owner); + return self->Owner; + } + else if (self->Object) { + self->Owner = PyAcquireItem_FromCpp(self->Object->Owner, false, NULL); + Py_INCREF(self->Owner); + return self->Owner; + } + Py_RETURN_NONE; +} + +static PyGetSetDef acquireitemdesc_getset[] = { + {"uri",acquireitemdesc_get_uri,0, + "The URI from which this item would be downloaded."}, + {"description",acquireitemdesc_get_description,0, + "A string describing the item."}, + {"shortdesc",acquireitemdesc_get_shortdesc,0, + "A short string describing the item (e.g. package name)."}, + {"owner",(getter)acquireitemdesc_get_owner,0, + "The owner of the item, an apt_pkg.AcquireItem object."}, + {NULL} +}; + +static char *acquireitemdesc_doc = + "Provide the description of an item and the URI the item is\n" + "fetched from. Progress classes make use of such objects to\n" + "retrieve description and other information about an item."; +PyTypeObject PyAcquireItemDesc_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.AcquireItemDesc", // tp_name + sizeof(CppPyObject),// tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_HAVE_GC), + acquireitemdesc_doc, // tp_doc + CppTraverse,// tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + acquireitemdesc_getset, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + 0, // tp_new +}; + +static PyObject *PkgAcquireRun(PyObject *Self,PyObject *Args) +{ + pkgAcquire *fetcher = GetCpp(Self); + + int pulseInterval = 500000; + if (PyArg_ParseTuple(Args, "|i", &pulseInterval) == 0) + return 0; + + pkgAcquire::RunResult run = fetcher->Run(pulseInterval); + + return HandleErrors(MkPyNumber(run)); +} + + +static PyObject *PkgAcquireShutdown(PyObject *Self,PyObject *Args) +{ + pkgAcquire *fetcher = GetCpp(Self); + if (PyArg_ParseTuple(Args, "") == 0) + return 0; + fetcher->Shutdown(); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyObject *PkgAcquireGetLock(PyObject *Self,PyObject *Args) +{ + pkgAcquire *fetcher = GetCpp(Self); + PyApt_Filename path; + if (PyArg_ParseTuple(Args, "O&", PyApt_Filename::Converter, &path) == 0) + return 0; + fetcher->GetLock(path); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + + + +static PyMethodDef PkgAcquireMethods[] = { + {"run",PkgAcquireRun,METH_VARARGS, + "run() -> int\n\nRun the fetcher and return one of RESULT_CANCELLED,\n" + "RESULT_CONTINUE, RESULT_FAILED.\n\n" + "RESULT_CONTINUE means that all items which where queued prior to\n" + "calling run() have been fetched successfully or failed transiently.\n\n" + "RESULT_CANCELLED means canceled by the progress class.\n\n" + "RESULT_FAILED means a generic failure."}, + {"shutdown",PkgAcquireShutdown, METH_VARARGS, + "shutdown()\n\n" + "Shut the fetcher down, removing all items from it. Future access to\n" + "queued AcquireItem objects will cause a segfault. The partial result\n" + "is kept on the disk and not removed and APT might reuse it."}, + {"get_lock",PkgAcquireGetLock, METH_VARARGS, + "get_lock(log: str)\n\n" + "Acquires a log for the given directory, using a file 'lock' in it."}, + {} +}; + +#define fetcher (GetCpp(Self)) +static PyObject *PkgAcquireGetTotalNeeded(PyObject *Self,void*) +{ + return MkPyNumber(fetcher->TotalNeeded()); +} +static PyObject *PkgAcquireGetFetchNeeded(PyObject *Self,void*) +{ + return MkPyNumber(fetcher->FetchNeeded()); +} +static PyObject *PkgAcquireGetPartialPresent(PyObject *Self,void*) +{ + return MkPyNumber(fetcher->PartialPresent()); +} +#undef fetcher + +static PyObject *PkgAcquireGetWorkers(PyObject *self, void *closure) +{ + PyObject *List = PyList_New(0); + pkgAcquire *Owner = GetCpp(self); + PyObject *PyWorker = NULL; + for (pkgAcquire::Worker *Worker = Owner->WorkersBegin(); + Worker != 0; Worker = Owner->WorkerStep(Worker)) { + PyWorker = PyAcquireWorker_FromCpp(Worker, false, self); + PyList_Append(List, PyWorker); + Py_DECREF(PyWorker); + } + return List; +} +static PyObject *PkgAcquireGetItems(PyObject *Self,void*) +{ + pkgAcquire *fetcher = GetCpp(Self); + PyObject *List = PyList_New(0); + PyObject *Obj; + for (pkgAcquire::ItemIterator I = fetcher->ItemsBegin(); + I != fetcher->ItemsEnd(); I++) { + Obj = PyAcquireItem_FromCpp(*I, false, Self); + PyList_Append(List,Obj); + Py_DECREF(Obj); + } + return List; +} + +static PyGetSetDef PkgAcquireGetSet[] = { + {"fetch_needed",PkgAcquireGetFetchNeeded,0, + "The total amount of data to be fetched (number of bytes)."}, + {"items",PkgAcquireGetItems,0, + "A list of all items as apt_pkg.AcquireItem objects, including already\n" + "fetched ones and to be fetched ones."}, + {"workers",PkgAcquireGetWorkers,0, + "A list of all active workers as apt_pkg.AcquireWorker objects."}, + {"partial_present",PkgAcquireGetPartialPresent,0, + "The amount of data which is already available (number of bytes)."}, + {"total_needed",PkgAcquireGetTotalNeeded,0, + "The amount of data that needs to fetched plus the amount of data\n" + "which has already been fetched (number of bytes)."}, + {} +}; + +static PyObject *PkgAcquireNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) +{ + pkgAcquire *fetcher; + + PyObject *pyFetchProgressInst = NULL; + char *kwlist[] = {"progress", 0}; + if (PyArg_ParseTupleAndKeywords(Args,kwds,"|O",kwlist,&pyFetchProgressInst) == 0) + return 0; + + PyFetchProgress *progress = 0; + if (pyFetchProgressInst != NULL) { + // FIXME: memleak? + progress = new PyFetchProgress(); + progress->setCallbackInst(pyFetchProgressInst); + } + + fetcher = new pkgAcquire(); + fetcher->SetLog(progress); + + PyObject *FetcherObj = CppPyObject_NEW(NULL, type, fetcher); + + if (progress != 0) + progress->setPyAcquire(FetcherObj); + // prepare our map of items. + return HandleErrors(FetcherObj); +} + +/** + * Create a new apt_pkg.Acquire Python object from the pkgAcquire object. + */ +PyObject *PyAcquire_FromCpp(pkgAcquire *fetcher, bool Delete, PyObject *owner) { + CppPyObject *obj = CppPyObject_NEW(owner, &PyAcquire_Type, fetcher); + obj->NoDelete = (!Delete); + return obj; +} + +static char *doc_PkgAcquire = + "Acquire([progress: apt.progress.base.AcquireProgress])\n\n" + "Coordinate the retrieval of files via network or local file system\n" + "(using 'copy:/path/to/file' style URIs). The optional argument\n" + "'progress' takes an apt.progress.base.AcquireProgress object\n" + "which may report progress information."; + +PyTypeObject PyAcquire_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Acquire", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE), + doc_PkgAcquire, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgAcquireMethods, // tp_methods + 0, // tp_members + PkgAcquireGetSet, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PkgAcquireNew, // tp_new +}; + + diff --git a/python/apt_instmodule.cc b/python/apt_instmodule.cc new file mode 100644 index 0000000..eb01074 --- /dev/null +++ b/python/apt_instmodule.cc @@ -0,0 +1,87 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: apt_instmodule.cc,v 1.3 2002/01/08 06:53:04 jgg Exp $ +/* ###################################################################### + + apt_intmodule - Top level for the python module. Create the internal + structures for the module in the interpriter. + + Note, this module shares state (particularly global config) with the + apt_pkg module. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "apt_instmodule.h" +#include "generic.h" + +#include +#include + +#include +#include +#include + /*}}}*/ + +PyObject *PyAptError; +PyObject *PyAptWarning; +static PyMethodDef *methods = 0; + + +static const char *apt_inst_doc = + "Functions for working with ar/tar archives and .deb packages.\n\n" + "This module provides useful classes and functions to work with\n" + "archives, modelled after the 'TarFile' class in the 'tarfile' module."; +#define ADDTYPE(mod,name,type) { \ + if (PyType_Ready(type) == -1) RETURN(0); \ + Py_INCREF(type); \ + PyModule_AddObject(mod,name,(PyObject *)type); } + + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "apt_inst", + apt_inst_doc, + -1, + methods, + 0, + 0, + 0, + 0 +}; +#define RETURN(x) return x +#define INIT_ERROR return 0 +extern "C" PyObject * PyInit_apt_inst() +#else +#define INIT_ERROR return +extern "C" void initapt_inst() +#define RETURN(x) return +#endif +{ +#if PY_MAJOR_VERSION >= 3 + PyObject *module = PyModule_Create(&moduledef); +#else + PyObject *module = Py_InitModule3("apt_inst",methods, apt_inst_doc); +#endif + + PyObject *apt_pkg = PyImport_ImportModule("apt_pkg"); + if (apt_pkg == NULL) + INIT_ERROR; + PyAptError = PyObject_GetAttrString(apt_pkg, "Error"); + if (PyAptError == NULL) + INIT_ERROR; + PyAptWarning = PyObject_GetAttrString(apt_pkg, "Warning"); + if (PyAptWarning == NULL) + INIT_ERROR; + + PyModule_AddObject(module,"Error",PyAptError); + PyModule_AddObject(module,"Warning",PyAptWarning); + ADDTYPE(module,"ArMember",&PyArMember_Type); + ADDTYPE(module,"ArArchive",&PyArArchive_Type); + ADDTYPE(module,"DebFile",&PyDebFile_Type); + ADDTYPE(module,"TarFile",&PyTarFile_Type); + ADDTYPE(module,"TarMember",&PyTarMember_Type); + ADDTYPE(module,"__FileFd",&PyFileFd_Type); + RETURN(module); +} diff --git a/python/apt_instmodule.h b/python/apt_instmodule.h new file mode 100644 index 0000000..92c9800 --- /dev/null +++ b/python/apt_instmodule.h @@ -0,0 +1,29 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: apt_instmodule.h,v 1.2 2002/01/08 06:53:04 jgg Exp $ +/* ###################################################################### + + Prototypes for the module + + ##################################################################### */ + /*}}}*/ +#ifndef APT_INSTMODULE_H +#define APT_INSTMODULE_H + +#include +#include "generic.h" +#include + + +extern PyTypeObject PyArMember_Type; +extern PyTypeObject PyArArchive_Type; +extern PyTypeObject PyDebFile_Type; +extern PyTypeObject PyTarFile_Type; +extern PyTypeObject PyTarMember_Type; +extern PyTypeObject PyFileFd_Type; +struct PyTarFileObject : public CppPyObject { + int min; + FileFd Fd; +}; + +#endif diff --git a/python/apt_pkgmodule.cc b/python/apt_pkgmodule.cc new file mode 100644 index 0000000..84b1e92 --- /dev/null +++ b/python/apt_pkgmodule.cc @@ -0,0 +1,1117 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: apt_pkgmodule.cc,v 1.5 2003/07/23 02:20:24 mdz Exp $ +/* ###################################################################### + + apt_pkgmodule - Top level for the python module. Create the internal + structures for the module in the interpriter. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "apt_pkgmodule.h" +#include "generic.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + /*}}}*/ + +static char PyAptError_Doc[] = + "Exception class for most python-apt exceptions.\n" + "\n" + "This class replaces the use of :class:`SystemError` in previous versions\n" + "of python-apt. It inherits from :class:`SystemError`, so make sure to\n" + "catch this class first.\n\n" + ".. versionadded:: 1.1"; + +PyObject *PyAptError; + +static char PyAptWarning_Doc[] = + "Exception class for most python-apt warnings.\n" + "\n" + ".. versionadded:: 2.7"; + +PyObject *PyAptWarning; + +static char PyAptCacheMismatchError_Doc[] = + "Raised when passing an object from a different cache to\n" + ":class:`apt_pkg.DepCache` methods\n\n" + ".. versionadded:: 1.6.1"; + +PyObject *PyAptCacheMismatchError; + +/** + * A Python->C->Python gettext() function. + * + * Python's gettext() ignores setlocale() which causes a strange behavior + * because the values received from apt-pkg respect setlocale(). We circumvent + * this problem by calling the C version of gettext(). This is also much + * faster. + */ +static PyObject *py_gettext(PyObject *self, PyObject *Args) { + const char *msg; + char *domain = "python-apt"; + if (PyArg_ParseTuple(Args,"s|s:gettext",&msg, &domain) == 0) + return 0; + + return CppPyString(dgettext(domain, msg)); +} + +// newConfiguration - Build a new configuration class /*{{{*/ +// --------------------------------------------------------------------- + /*}}}*/ + +// Version Wrappers /*{{{*/ +// These are kind of legacy.. +static char *doc_VersionCompare = + "version_compare(a: str, b: str) -> int\n\n" + "Compare the given versions; return a strictly negative value if 'a' is \n" + "smaller than 'b', 0 if they are equal, and a strictly positive value if\n" + "'a' is larger than 'b'."; +static PyObject *VersionCompare(PyObject *Self,PyObject *Args) +{ + char *A; + char *B; + Py_ssize_t LenA; + Py_ssize_t LenB; + + if (PyArg_ParseTuple(Args,"s#s#",&A,&LenA,&B,&LenB) == 0) + return 0; + + if (_system == 0) + { + PyErr_SetString(PyExc_ValueError,"_system not initialized"); + return 0; + } + + return MkPyNumber(_system->VS->DoCmpVersion(A,A+LenA,B,B+LenB)); +} + +static char *doc_CheckDep = + "check_dep(pkg_ver: str, dep_op: str, dep_ver: str) -> bool\n\n" + "Check that the given requirement is fulfilled; i.e. that the version\n" + "string given by 'pkg_ver' matches the version string 'dep_ver' under\n" + "the condition specified by the operator 'dep_op' (<,<=,=,>=,>).\n\n" + "Return True if 'pkg_ver' matches 'dep_ver' under the\n" + "condition 'dep_op'; for example, this returns True:\n\n" + " apt_pkg.check_dep('1', '<=', '2')"; +static PyObject *CheckDep(PyObject *Self,PyObject *Args) +{ + char *A; + char *B; + char *OpStr; + unsigned int Op = 0; + + if (PyArg_ParseTuple(Args,"sss",&A,&OpStr,&B) == 0) + return 0; + + if (strcmp(OpStr, ">") == 0) OpStr = ">>"; + if (strcmp(OpStr, "<") == 0) OpStr = "<<"; + if (*debListParser::ConvertRelation(OpStr,Op) != 0) + { + PyErr_SetString(PyExc_ValueError,"Bad comparison operation"); + return 0; + } + + if (_system == 0) + { + PyErr_SetString(PyExc_ValueError,"_system not initialized"); + return 0; + } + + return PyBool_FromLong(_system->VS->CheckDep(A,Op,B)); +} + + +static char *doc_UpstreamVersion = + "upstream_version(ver: str) -> str\n\n" + "Return the upstream version for the package version given by 'ver'."; +static PyObject *UpstreamVersion(PyObject *Self,PyObject *Args) +{ + char *Ver; + if (PyArg_ParseTuple(Args,"s",&Ver) == 0) + return 0; + return CppPyString(_system->VS->UpstreamVersion(Ver)); +} + +static const char *doc_ParseDepends = +"parse_depends(s: str[, strip_multi_arch : bool = True[, architecture : string]]) -> list\n" +"\n" +"Parse the dependencies given by 's' and return a list of lists. Each of\n" +"these lists represents one or more options for an 'or' dependency in\n" +"the form of '(pkg, ver, comptype)' tuples. The tuple element 'pkg'\n" +"is the name of the package; the element 'ver' is the version, or ''\n" +"if no version was requested. The element 'ver' is a comparison\n" +"operator ('<', '<=', '=', '>=', or '>').\n\n" +"If 'strip_multi_arch' is True, :any (and potentially other special values)\n" +"will be stripped from the full package name" +"The 'architecture' parameter may be used to specify a non-native architecture\n" +"for the dependency parsing."; + +static const char *parse_src_depends_doc = +"parse_src_depends(s: str[, strip_multi_arch : bool = True[, architecture : string]]) -> list\n" +"\n" +"Parse the dependencies given by 's' and return a list of lists. Each of\n" +"these lists represents one or more options for an 'or' dependency in\n" +"the form of '(pkg, ver, comptype)' tuples. The tuple element 'pkg'\n" +"is the name of the package; the element 'ver' is the version, or ''\n" +"if no version was requested. The element 'ver' is a comparison\n" +"operator ('<', '<=', '=', '>=', or '>')." +"\n\n" +"Dependencies may be restricted to certain architectures and the result\n" +"only contains those dependencies for the architecture set in the\n" +"configuration variable APT::Architecture\n\n" +"If 'strip_multi_arch' is True, :any (and potentially other special values)\n" +"will be stripped from the full package name" +"The 'architecture' parameter may be used to specify a non-native architecture\n" +"for the dependency parsing."; +static PyObject *RealParseDepends(PyObject *Self,PyObject *Args,PyObject *Kwds, + bool ParseArchFlags, bool ParseRestrictionsList, + std::string name, bool debStyle=false) +{ + std::string Package; + std::string Version; + unsigned int Op; + bool StripMultiArch=true; + + const char *Start; + const char *Stop; + Py_ssize_t Len; + const char *Arch = NULL; + char *kwlist[] = {"s", "strip_multi_arch", "architecture", 0}; + + if (PyArg_ParseTupleAndKeywords(Args,Kwds,(char *)("s#|bs:" + name).c_str(), kwlist, + &Start, &Len, &StripMultiArch, &Arch) == 0) + return 0; + Stop = Start + Len; + PyObject *List = PyList_New(0); + PyObject *LastRow = 0; + while (1) + { + if (Start == Stop) + break; + if (Arch == NULL) + Start = debListParser::ParseDepends(Start,Stop,Package,Version,Op, + ParseArchFlags, StripMultiArch, + ParseRestrictionsList); + else + Start = debListParser::ParseDepends(Start,Stop,Package,Version,Op, + ParseArchFlags, StripMultiArch, + ParseRestrictionsList, Arch); + + if (Start == 0) + { + PyErr_SetString(PyExc_ValueError,"Problem Parsing Dependency"); + Py_DECREF(List); + return 0; + } + + if (LastRow == 0) + LastRow = PyList_New(0); + + if (Package.empty() == false) + { + PyObject *Obj; + PyList_Append(LastRow,Obj = Py_BuildValue("sss",Package.c_str(), + Version.c_str(), + debStyle ? pkgCache::CompTypeDeb(Op) : pkgCache::CompType(Op))); + Py_DECREF(Obj); + } + + // Group ORd deps into a single row.. + if ((Op & pkgCache::Dep::Or) != pkgCache::Dep::Or) + { + if (PyList_Size(LastRow) != 0) + PyList_Append(List,LastRow); + Py_DECREF(LastRow); + LastRow = 0; + } + } + return List; +} +static PyObject *ParseDepends(PyObject *Self,PyObject *Args, PyObject *Kwds) +{ + return RealParseDepends(Self, Args, Kwds, false, false, "parse_depends"); +} +static PyObject *ParseSrcDepends(PyObject *Self,PyObject *Args, PyObject *Kwds) +{ + return RealParseDepends(Self, Args, Kwds, true, true, "parse_src_depends"); +} + /*}}}*/ +// md5sum - Compute the md5sum of a file or string /*{{{*/ +// --------------------------------------------------------------------- +static const char *doc_md5sum = + "md5sum(object) -> str\n\n" + "Return the md5sum of the object. 'object' may either be a string, in\n" + "which case the md5sum of the string is returned, or a file() object\n" + "(or file descriptor), in which case the md5sum of its contents is\n" + "returned."; +static PyObject *md5sum(PyObject *Self,PyObject *Args) +{ + PyObject *Obj; + if (PyArg_ParseTuple(Args,"O",&Obj) == 0) + return 0; + + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "apt_pkg.md5sum is deprecated, use apt_pkg.Hashes", 1) == -1) + return NULL; + + // Digest of a string. + if (PyBytes_Check(Obj) != 0) + { + char *s; + Py_ssize_t len; + Hashes Sum(Hashes::MD5SUM); + PyBytes_AsStringAndSize(Obj, &s, &len); + Sum.Add((const unsigned char*)s, len); + return CppPyString(Sum.GetHashString(Hashes::MD5SUM).HashValue()); + } + + // Digest of a file + int Fd = PyObject_AsFileDescriptor(Obj); + if (Fd != -1) + { + Hashes Sum(Hashes::MD5SUM); + struct stat St; + if (fstat(Fd,&St) != 0 || + Sum.AddFD(Fd,St.st_size) == false) + { + PyErr_SetFromErrno(PyAptError); + return 0; + } + + return CppPyString(Sum.GetHashString(Hashes::MD5SUM).HashValue()); + } + + PyErr_SetString(PyExc_TypeError,"Only understand strings and files"); + return 0; +} + /*}}}*/ +// sha1sum - Compute the sha1sum of a file or string /*{{{*/ +// --------------------------------------------------------------------- +static const char *doc_sha1sum = + "sha1sum(object) -> str\n\n" + "Return the sha1sum of the object. 'object' may either be a string, in\n" + "which case the sha1sum of the string is returned, or a file() object\n" + "(or file descriptor), in which case the sha1sum of its contents is\n" + "returned."; +static PyObject *sha1sum(PyObject *Self,PyObject *Args) +{ + PyObject *Obj; + if (PyArg_ParseTuple(Args,"O",&Obj) == 0) + return 0; + + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "apt_pkg.sha1sum is deprecated, use apt_pkg.Hashes", 1) == -1) + return NULL; + + // Digest of a string. + if (PyBytes_Check(Obj) != 0) + { + char *s; + Py_ssize_t len; + Hashes Sum(Hashes::SHA1SUM); + PyBytes_AsStringAndSize(Obj, &s, &len); + Sum.Add((const unsigned char*)s, len); + return CppPyString(Sum.GetHashString(Hashes::SHA1SUM).HashValue()); + } + + // Digest of a file + int Fd = PyObject_AsFileDescriptor(Obj); + if (Fd != -1) + { + Hashes Sum(Hashes::SHA1SUM); + struct stat St; + if (fstat(Fd,&St) != 0 || + Sum.AddFD(Fd,St.st_size) == false) + { + PyErr_SetFromErrno(PyAptError); + return 0; + } + + return CppPyString(Sum.GetHashString(Hashes::SHA1SUM).HashValue()); + } + + PyErr_SetString(PyExc_TypeError,"Only understand strings and files"); + return 0; +} + /*}}}*/ +// sha256sum - Compute the sha256sum of a file or string /*{{{*/ +// --------------------------------------------------------------------- +static const char *doc_sha256sum = + "sha256sum(object) -> str\n\n" + "Return the sha256sum of the object. 'object' may either be a string, in\n" + "which case the sha256sum of the string is returned, or a file() object\n" + "(or file descriptor), in which case the sha256sum of its contents is\n" + "returned.";; +static PyObject *sha256sum(PyObject *Self,PyObject *Args) +{ + PyObject *Obj; + if (PyArg_ParseTuple(Args,"O",&Obj) == 0) + return 0; + + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "apt_pkg.sha256sum is deprecated, use apt_pkg.Hashes", 1) == -1) + return NULL; + + // Digest of a string. + if (PyBytes_Check(Obj) != 0) + { + char *s; + Py_ssize_t len; + Hashes Sum(Hashes::SHA256SUM); + PyBytes_AsStringAndSize(Obj, &s, &len); + Sum.Add((const unsigned char*)s, len); + return CppPyString(Sum.GetHashString(Hashes::SHA256SUM).HashValue()); + } + + // Digest of a file + int Fd = PyObject_AsFileDescriptor(Obj); + if (Fd != -1) + { + Hashes Sum(Hashes::SHA256SUM); + struct stat St; + if (fstat(Fd,&St) != 0 || + Sum.AddFD(Fd,St.st_size) == false) + { + PyErr_SetFromErrno(PyAptError); + return 0; + } + + return CppPyString(Sum.GetHashString(Hashes::SHA256SUM).HashValue()); + } + + PyErr_SetString(PyExc_TypeError,"Only understand strings and files"); + return 0; +} + /*}}}*/ +// sha512sum - Compute the sha512sum of a file or string /*{{{*/ +// --------------------------------------------------------------------- +static const char *doc_sha512sum = + "sha512sum(object) -> str\n\n" + "Return the sha512sum of the object. 'object' may either be a string, in\n" + "which case the sha512sum of the string is returned, or a file() object\n" + "(or file descriptor), in which case the sha512sum of its contents is\n" + "returned.";; +static PyObject *sha512sum(PyObject *Self,PyObject *Args) +{ + PyObject *Obj; + if (PyArg_ParseTuple(Args,"O",&Obj) == 0) + return 0; + + if (PyErr_WarnEx(PyExc_DeprecationWarning, + "apt_pkg.sha512sum is deprecated, use apt_pkg.Hashes", 1) == -1) + return NULL; + + // Digest of a string. + if (PyBytes_Check(Obj) != 0) + { + char *s; + Py_ssize_t len; + Hashes Sum(Hashes::SHA512SUM); + PyBytes_AsStringAndSize(Obj, &s, &len); + Sum.Add((const unsigned char*)s, len); + return CppPyString(Sum.GetHashString(Hashes::SHA512SUM).HashValue()); + } + + // Digest of a file + int Fd = PyObject_AsFileDescriptor(Obj); + if (Fd != -1) + { + Hashes Sum(Hashes::SHA512SUM); + struct stat St; + if (fstat(Fd,&St) != 0 || + Sum.AddFD(Fd,St.st_size) == false) + { + PyErr_SetFromErrno(PyAptError); + return 0; + } + + return CppPyString(Sum.GetHashString(Hashes::SHA512SUM).HashValue()); + } + + PyErr_SetString(PyExc_TypeError,"Only understand strings and files"); + return 0; +} + /*}}}*/ +// get_architectures - return the list of architectures /*{{{*/ +// --------------------------------------------------------------------- +static const char *doc_GetArchitectures = + "get_architectures() -> list\n\n" + "Return the list of supported architectures on this system. On a \n" + "multiarch system this can be more than one. The main architectures\n" + "is the first item in the list.";; +static PyObject *GetArchitectures(PyObject *Self,PyObject *Args) +{ + PyObject *Obj; + if (PyArg_ParseTuple(Args,"",&Obj) == 0) + return 0; + + PyObject *List = PyList_New(0); + std::vector arches = APT::Configuration::getArchitectures(); + std::vector::const_iterator I; + for (I = arches.begin(); I != arches.end(); I++) + { + PyList_Append(List, CppPyString(*I)); + } + + return List; +} + /*}}}*/ +// init - 3 init functions /*{{{*/ +// --------------------------------------------------------------------- +static char *doc_Init = +"init()\n\n" +"Shorthand for doing init_config() and init_system(). When working\n" +"with command line arguments, first call init_config() then parse\n" +"the command line and finally call init_system()."; +static PyObject *Init(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + pkgInitConfig(*_config); + pkgInitSystem(*_config,_system); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static char *doc_InitConfig = +"init_config()\n\n" +"Load the default configuration and the config file."; +static PyObject *InitConfig(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + pkgInitConfig(*_config); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static char *doc_InitSystem = +"init_system()\n\n" +"Construct the apt_pkg system."; +static PyObject *InitSystem(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + pkgInitSystem(*_config,_system); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + /*}}}*/ +// gpgv.cc:OpenMaybeClearSignedFile /*{{{*/ +// --------------------------------------------------------------------- +static char *doc_OpenMaybeClearSignedFile = +"open_maybe_clear_signed_file(file: str) -> int\n\n" +"Open a file and ignore a PGP clear signature.\n" +"Return a open file descriptor or a error."; +static PyObject *PyOpenMaybeClearSignedFile(PyObject *Self,PyObject *Args) +{ + PyApt_Filename file; + char errors = false; + if (PyArg_ParseTuple(Args,"O&",PyApt_Filename::Converter, &file,&errors) == 0) + return 0; + + FileFd Fd; + if (OpenMaybeClearSignedFile(file, Fd) == false) + return HandleErrors(MkPyNumber(-1)); + + return HandleErrors(MkPyNumber(dup(Fd.Fd()))); +} + +// fileutils.cc: GetLock /*{{{*/ +// --------------------------------------------------------------------- +static char *doc_GetLock = +"get_lock(file: str, errors: bool) -> int\n\n" +"Create an empty file of the given name and lock it. If the locking\n" +"succeeds, return the file descriptor of the lock file. Afterwards,\n" +"locking the file from another process will fail and thus cause\n" +"get_lock() to return -1 or raise an Error (if 'errors' is True).\n\n" +"From Python 2.6 on, it is recommended to use the context manager\n" +"provided by apt_pkg.FileLock instead using the with-statement."; +static PyObject *GetLock(PyObject *Self,PyObject *Args) +{ + PyApt_Filename file; + char errors = false; + if (PyArg_ParseTuple(Args,"O&|b",PyApt_Filename::Converter, &file,&errors) == 0) + return 0; + + int fd = GetLock(file, errors); + + return HandleErrors(MkPyNumber(fd)); +} + +static char *doc_PkgSystemLock = +"pkgsystem_lock() -> bool\n\n" +"Acquire the global lock for the package system by using /var/lib/dpkg/lock-frontend\n" +"and /var/lib/dpkg/lock to do the locking. From Python 2.6 on, the apt_pkg.SystemLock context\n" +"manager is available and should be used instead."; +static PyObject *PkgSystemLock(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + bool res = _system->Lock(); + + Py_INCREF(Py_None); + return HandleErrors(PyBool_FromLong(res)); +} + +static char *doc_PkgSystemUnLock = +"pkgsystem_unlock() -> bool\n\n" +"Release the global lock for the package system."; +static PyObject *PkgSystemUnLock(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + bool res = _system->UnLock(); + + Py_INCREF(Py_None); + return HandleErrors(PyBool_FromLong(res)); +} + +static char *doc_PkgSystemLockInner = +"pkgsystem_lock_inner() -> bool\n\n" +"Reacquire the dpkg 'lock' lock file. Must be called only after\n" +":meth:`pkgsystem_unlock_inner` and only around invocations of dpkg.\n" +"\n" +".. versionadded:: 1.7"; +static PyObject *PkgSystemLockInner(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + bool res = _system->LockInner(); + + Py_INCREF(Py_None); + return HandleErrors(PyBool_FromLong(res)); +} + +static char *doc_PkgSystemUnLockInner = +"pkgsystem_unlock_inner() -> bool\n\n" +"Release the dpkg lock file 'lock'. To be called before manually\n" +"invoking dpkg.\n" +"\n" +".. versionadded:: 1.7"; +static PyObject *PkgSystemUnLockInner(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + bool res = _system->UnLockInner(); + + Py_INCREF(Py_None); + return HandleErrors(PyBool_FromLong(res)); +} + +static char *doc_PkgSystemIsLocked = +"pkgsystem_is_locked() -> bool\n\n" +"Check if the system is locked. Can be used to check whether the inner\n" +"lock needs to be released or not in generic code.\n" +"\n" +".. versionadded:: 1.7"; +static PyObject *PkgSystemIsLocked(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + bool res = _system->IsLocked(); + + Py_INCREF(Py_None); + return HandleErrors(PyBool_FromLong(res)); +} + + /*}}}*/ + +// initapt_pkg - Core Module Initialization /*{{{*/ +// --------------------------------------------------------------------- +/* */ +static PyMethodDef methods[] = +{ + // Constructors + {"init",Init,METH_VARARGS,doc_Init}, + {"init_config",InitConfig,METH_VARARGS,doc_InitConfig}, + {"init_system",InitSystem,METH_VARARGS,doc_InitSystem}, + + // Internationalization. + {"gettext",py_gettext,METH_VARARGS, + "gettext(msg: str[, domain: str = 'python-apt']) -> str\n\n" + "Translate the given string. This is much faster than Python's version\n" + "and only does translations after setlocale() has been called."}, + + // Tag File + + {"open_maybe_clear_signed_file",PyOpenMaybeClearSignedFile,METH_VARARGS, + doc_OpenMaybeClearSignedFile}, + + // Locking + {"get_lock",GetLock,METH_VARARGS,doc_GetLock}, + {"pkgsystem_lock",PkgSystemLock,METH_VARARGS,doc_PkgSystemLock}, + {"pkgsystem_unlock",PkgSystemUnLock,METH_VARARGS,doc_PkgSystemUnLock}, + {"pkgsystem_lock_inner",PkgSystemLockInner,METH_VARARGS,doc_PkgSystemLockInner}, + {"pkgsystem_unlock_inner",PkgSystemUnLockInner,METH_VARARGS,doc_PkgSystemUnLockInner}, + {"pkgsystem_is_locked",PkgSystemIsLocked,METH_VARARGS,doc_PkgSystemIsLocked}, + + // Command line + {"read_config_file",LoadConfig,METH_VARARGS,doc_LoadConfig}, + {"read_config_dir",LoadConfigDir,METH_VARARGS,doc_LoadConfigDir}, + {"read_config_file_isc",LoadConfigISC,METH_VARARGS,doc_LoadConfig}, + {"parse_commandline",ParseCommandLine,METH_VARARGS,doc_ParseCommandLine}, + + // Versioning + {"version_compare",VersionCompare,METH_VARARGS,doc_VersionCompare}, + {"check_dep",CheckDep,METH_VARARGS,doc_CheckDep}, + {"upstream_version",UpstreamVersion,METH_VARARGS,doc_UpstreamVersion}, + + // Depends + {"parse_depends",reinterpret_cast(static_cast(ParseDepends)),METH_VARARGS|METH_KEYWORDS,doc_ParseDepends}, + {"parse_src_depends",reinterpret_cast(static_cast(ParseSrcDepends)),METH_VARARGS|METH_KEYWORDS,parse_src_depends_doc}, + + // Hashes + {"md5sum",md5sum,METH_VARARGS,doc_md5sum}, + {"sha1sum",sha1sum,METH_VARARGS,doc_sha1sum}, + {"sha256sum",sha256sum,METH_VARARGS,doc_sha256sum}, + {"sha512sum",sha512sum,METH_VARARGS,doc_sha512sum}, + + // multiarch + {"get_architectures", GetArchitectures, METH_VARARGS, doc_GetArchitectures}, + + // Strings + {"check_domain_list",StrCheckDomainList,METH_VARARGS, + "check_domain_list(host: str, domains: str) -> bool\n\n" + "Check if the host given by 'host' belongs to one of the domains\n" + "specified in the comma separated string 'domains'. An example\n" + "would be:\n\n" + " check_domain_list('alioth.debian.org','debian.net,debian.org')\n\n" + "which would return True because alioth belongs to debian.org."}, + {"quote_string",StrQuoteString,METH_VARARGS, + "quote_string(string: str, repl: str) -> str\n\n" + "Escape the string 'string', replacing any character not allowed in a URL" + "or specified by 'repl' with its ASCII value preceded by a percent sign" + "(so for example ' ' becomes '%20')."}, + {"dequote_string",StrDeQuote,METH_VARARGS, + "dequote_string(string: str) -> str\n\n" + "Dequote the given string by replacing all HTTP encoded values such\n" + "as '%20' with their decoded value (in this case, ' ')."}, + {"size_to_str",StrSizeToStr,METH_VARARGS, + "size_to_str(bytes: int) -> str\n\n" + "Return a string describing the size in a human-readable manner using\n" + "SI prefix and base-10 units, e.g. '1k' for 1000, '1M' for 1000000, etc."}, + {"time_to_str",StrTimeToStr,METH_VARARGS, + "time_to_str(seconds: int) -> str\n\n" + "Return a string describing the number of seconds in a human\n" + "readable manner using days, hours, minutes and seconds."}, + {"uri_to_filename",StrURItoFileName,METH_VARARGS, + "uri_to_filename(uri: str) -> str\n\n" + "Return a filename based on the given URI after replacing some\n" + "parts not suited for filenames (e.g. '/')."}, + {"base64_encode",StrBase64Encode,METH_VARARGS, + "base64_encode(value: bytes) -> str\n\n" + "Encode the given bytestring into Base64. The input may not\n" + "contain a null byte character (use the base64 module for this)."}, + {"string_to_bool",StrStringToBool,METH_VARARGS, + "string_to_bool(string: str) -> int\n\n" + "Return 1 if the string is a value such as 'yes', 'true', '1';\n" + "0 if the string is a value such as 'no', 'false', '0'; -1 if\n" + "the string is not recognized."}, + {"time_rfc1123",StrTimeRFC1123,METH_VARARGS, + "time_rfc1123(unixtime: int) -> str\n\n" + "Format the given Unix time according to the requirements of\n" + "RFC 1123."}, + {"str_to_time",StrStrToTime,METH_VARARGS, + "str_to_time(rfc_time: str) -> int\n\n" + "Convert the given RFC 1123 formatted string to a Unix timestamp."}, + + // DEPRECATED + + {} +}; + +static struct _PyAptPkgAPIStruct API = { + &PyAcquire_Type, // acquire_type + &PyAcquire_FromCpp, // acquire_fromcpp + &PyAcquire_ToCpp, // acquire_tocpp + &PyAcquireFile_Type, // acquirefile_type + &PyAcquireFile_FromCpp, // acquirefile_fromcpp + &PyAcquireFile_ToCpp, // acquirefile_tocpp + &PyAcquireItem_Type, // acquireitem_type + &PyAcquireItem_FromCpp, // acquireitem_fromcpp + &PyAcquireItem_ToCpp, // acquireitem_type + &PyAcquireItemDesc_Type, // acquireitemdesc_type + &PyAcquireItemDesc_FromCpp,// acquireitemdesc_fromcpp + &PyAcquireItemDesc_ToCpp, // acquireitemdesc_tocpp + &PyAcquireWorker_Type, // acquireworker_type + &PyAcquireWorker_FromCpp, // acquireworker_fromcpp + &PyAcquireWorker_ToCpp, // acquireworker_tocpp + &PyActionGroup_Type, // actiongroup_type + &PyActionGroup_FromCpp, // actiongroup_fromcpp + &PyActionGroup_ToCpp, // actiongroup_tocpp + &PyCache_Type, // cache_type + &PyCache_FromCpp, // cache_fromcpp + &PyCache_ToCpp, // cache_tocpp + &PyCacheFile_Type, // cachefile_type + &PyCacheFile_FromCpp, // cachefile_fromcpp + &PyCacheFile_ToCpp, // cachefile_tocpp + &PyCdrom_Type, // cdrom_type + &PyCdrom_FromCpp, // cdrom_fromcpp + &PyCdrom_ToCpp, // cdrom_tocpp + &PyConfiguration_Type, // configuration_type + &PyConfiguration_FromCpp, // configuration_fromcpp + &PyConfiguration_ToCpp, // configuration_tocpp + &PyDepCache_Type, // depcache_type + &PyDepCache_FromCpp, // depcache_fromcpp + &PyDepCache_ToCpp, // depcache_tocpp + &PyDependency_Type, // dependency_type + &PyDependency_FromCpp, // dependency_fromcpp + &PyDependency_ToCpp, // dependency_tocpp + &PyDependencyList_Type, // dependencylist_type + 0, // FIXME: dependencylist_fromcpp + 0, // FIXME: dependencylist_tocpp + &PyDescription_Type, // description_type + &PyDescription_FromCpp, // description_fromcpp + &PyDescription_ToCpp, // description_tocpp + &PyHashes_Type, // hashes_type + &PyHashes_FromCpp, // hashes_fromcpp + &PyHashes_ToCpp, // hashes_tocpp + &PyHashString_Type, // hashstring_type + &PyHashString_FromCpp, // hashstring_fromcpp + &PyHashString_ToCpp, // hashstring_tocpp + &PyMetaIndex_Type, // metaindex_type + &PyMetaIndex_FromCpp, // metaindex_tocpp + &PyMetaIndex_ToCpp, // metaindex_tocpp + &PyPackage_Type, // package_type + &PyPackage_FromCpp, // package_tocpp + &PyPackage_ToCpp, // package_tocpp + &PyPackageFile_Type, // packagefile_type + &PyPackageFile_FromCpp, // packagefile_tocpp + &PyPackageFile_ToCpp, // packagefile_tocpp + &PyIndexFile_Type, // packageindexfile_type + &PyIndexFile_FromCpp, // packageindexfile_tocpp + &PyIndexFile_ToCpp, // packageindexfile_tocpp + &PyPackageList_Type, // packagelist_type + 0, // FIXME: packagelist_fromcpp + 0, // FIXME: packagelist_tocpp + &PyPackageManager_Type, // packagemanager_type + &PyPackageManager_FromCpp, // packagemanager_type + &PyPackageManager_ToCpp, // packagemanager_type + &PyPackageRecords_Type, // packagerecords_type + 0, // FIXME: packagerecords_fromcpp + 0, // FIXME: packagerecords_tocpp + &PyPolicy_Type, // policy_type + &PyPolicy_FromCpp, // policy_tocpp + &PyPolicy_ToCpp, // policy_tocpp + &PyProblemResolver_Type, // problemresolver_type + &PyProblemResolver_FromCpp, // problemresolver_tocpp + &PyProblemResolver_ToCpp, // problemresolver_tocpp + &PySourceList_Type, // sourcelist_type + &PySourceList_FromCpp, // sourcelist_tocpp + &PySourceList_ToCpp, // sourcelist_tocpp + &PySourceRecords_Type, // sourcerecords_type + 0, // FIXME: sourcerecords_fromcpp + 0, // FIXME: sourcerecords_tocpp + &PyTagFile_Type, // tagfile_type + &PyTagFile_FromCpp, // tagfile_tocpp + &PyTagFile_ToCpp, // tagfile_tocpp + &PyTagSection_Type, // tagsection_type + &PyTagSection_FromCpp, // tagsection_tocpp + &PyTagSection_ToCpp, // tagsection_tocpp + &PyVersion_Type, // version_type + &PyVersion_FromCpp, // version_tocpp + &PyVersion_ToCpp, // version_tocpp + &PyGroup_Type, // group_type + &PyGroup_FromCpp, // group_fromcpp + &PyGroup_ToCpp, // group_tocpp + &PyOrderList_Type, // orderlist_type + &PyOrderList_FromCpp, // orderlist_fromcpp + &PyOrderList_ToCpp, // orderlist_tocpp + &PySourceRecordFiles_Type, // sourcerecordfiles_type + 0, // FIXME: sourcerecordfiles_fromcpp + 0, // FIXME: sourcerecordfiles_tocpp +}; + + +#define ADDTYPE(mod,name,type) { \ + if (PyType_Ready(type) == -1) INIT_ERROR; \ + Py_INCREF(type); \ + PyModule_AddObject(mod,name,(PyObject *)type); } + + +static const char *apt_pkg_doc = + "Classes and functions wrapping the apt-pkg library.\n\n" + "The apt_pkg module provides several classes and functions for accessing\n" + "the functionality provided by the apt-pkg library. Typical uses might\n" + "include reading APT index files and configuration files and installing\n" + "or removing packages."; + +#if PY_MAJOR_VERSION >= 3 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "apt_pkg", + apt_pkg_doc, + -1, + methods, + 0, + 0, + 0, + 0, +}; + +#define INIT_ERROR return 0 +extern "C" PyObject * PyInit_apt_pkg() +#else +#define INIT_ERROR return +extern "C" void initapt_pkg() +#endif +{ + // Finalize our types to add slots, etc. + if (PyType_Ready(&PyConfiguration_Type) == -1) INIT_ERROR; + if (PyType_Ready(&PyCacheFile_Type) == -1) INIT_ERROR; + PyAptError = PyErr_NewExceptionWithDoc("apt_pkg.Error", PyAptError_Doc, PyExc_SystemError, NULL); + if (PyAptError == NULL) + INIT_ERROR; + PyAptWarning = PyErr_NewExceptionWithDoc("apt_pkg.Warning", PyAptWarning_Doc, PyExc_Warning, NULL); + if (PyAptWarning == NULL) + INIT_ERROR; + + PyAptCacheMismatchError = PyErr_NewExceptionWithDoc("apt_pkg.CacheMismatchError", PyAptCacheMismatchError_Doc, PyExc_ValueError, NULL); + if (PyAptCacheMismatchError == NULL) + INIT_ERROR; + + // Initialize the module + #if PY_MAJOR_VERSION >= 3 + PyObject *Module = PyModule_Create(&moduledef); + #else + PyObject *Module = Py_InitModule3("apt_pkg",methods, apt_pkg_doc); + #endif + + // Global variable linked to the global configuration class + CppPyObject *Config = CppPyObject_NEW(NULL, &PyConfiguration_Type); + Config->Object = _config; + // Global configuration, should never be deleted. + Config->NoDelete = true; + PyModule_AddObject(Module,"config",Config); + PyModule_AddObject(Module,"Error",PyAptError); + PyModule_AddObject(Module,"Warning",PyAptWarning); + PyModule_AddObject(Module,"CacheMismatchError", PyAptCacheMismatchError); + + + + // Add our classes. + /* ============================ tag.cc ============================ */ + ADDTYPE(Module,"TagSection",&PyTagSection_Type); + ADDTYPE(Module,"TagFile",&PyTagFile_Type); + ADDTYPE(Module,"Tag",&PyTag_Type); + ADDTYPE(Module,"TagRewrite",&PyTagRewrite_Type); + ADDTYPE(Module,"TagRename",&PyTagRename_Type); + ADDTYPE(Module,"TagRemove",&PyTagRemove_Type); + /* ============================ acquire.cc ============================ */ + ADDTYPE(Module,"Acquire",&PyAcquire_Type); + ADDTYPE(Module,"AcquireFile",&PyAcquireFile_Type); + ADDTYPE(Module,"AcquireItem",&PyAcquireItem_Type); // NO __new__() + ADDTYPE(Module,"AcquireWorker",&PyAcquireWorker_Type); // NO __new__() + /* ============================ cache.cc ============================ */ + ADDTYPE(Module,"Cache",&PyCache_Type); + ADDTYPE(Module,"Dependency",&PyDependency_Type); // NO __new__() + ADDTYPE(Module,"Description",&PyDescription_Type); // NO __new__() + ADDTYPE(Module,"PackageFile",&PyPackageFile_Type); // NO __new__() + ADDTYPE(Module,"PackageList",&PyPackageList_Type); // NO __new__(), internal + ADDTYPE(Module,"DependencyList",&PyDependencyList_Type); // NO __new__(), internal + ADDTYPE(Module,"Package",&PyPackage_Type); // NO __new__() + ADDTYPE(Module,"Version",&PyVersion_Type); // NO __new__() + ADDTYPE(Module,"Group", &PyGroup_Type); + ADDTYPE(Module,"GroupList", &PyGroupList_Type); + /* ============================ cdrom.cc ============================ */ + ADDTYPE(Module,"Cdrom",&PyCdrom_Type); + /* ========================= configuration.cc ========================= */ + ADDTYPE(Module,"Configuration",&PyConfiguration_Type); + /* ========================= depcache.cc ========================= */ + ADDTYPE(Module,"ActionGroup",&PyActionGroup_Type); + ADDTYPE(Module,"DepCache",&PyDepCache_Type); + ADDTYPE(Module,"ProblemResolver",&PyProblemResolver_Type); + /* ========================= indexfile.cc ========================= */ + ADDTYPE(Module,"IndexFile",&PyIndexFile_Type); // NO __new__() + /* ========================= metaindex.cc ========================= */ + ADDTYPE(Module,"MetaIndex",&PyMetaIndex_Type); // NO __new__() + /* ========================= pkgmanager.cc ========================= */ + ADDTYPE(Module,"_PackageManager",&PyPackageManager_Type); + ADDTYPE(Module,"PackageManager",&PyPackageManager2_Type); + /* ========================= pkgrecords.cc ========================= */ + ADDTYPE(Module,"PackageRecords",&PyPackageRecords_Type); + /* ========================= pkgsrcrecords.cc ========================= */ + ADDTYPE(Module,"SourceRecords",&PySourceRecords_Type); + ADDTYPE(Module,"SourceRecordFiles",&PySourceRecordFiles_Type); + /* ========================= sourcelist.cc ========================= */ + ADDTYPE(Module,"SourceList",&PySourceList_Type); + ADDTYPE(Module,"HashString",&PyHashString_Type); + ADDTYPE(Module,"Policy",&PyPolicy_Type); + ADDTYPE(Module,"Hashes",&PyHashes_Type); + ADDTYPE(Module,"AcquireItemDesc",&PyAcquireItemDesc_Type); + ADDTYPE(Module,"SystemLock",&PySystemLock_Type); + ADDTYPE(Module,"FileLock",&PyFileLock_Type); + ADDTYPE(Module,"OrderList",&PyOrderList_Type); + ADDTYPE(Module,"HashStringList",&PyHashStringList_Type); + // Tag file constants + PyModule_AddObject(Module,"REWRITE_PACKAGE_ORDER", + CharCharToList(TFRewritePackageOrder)); + + PyModule_AddObject(Module,"REWRITE_SOURCE_ORDER", + CharCharToList(TFRewriteSourceOrder)); + + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_ADDED", MkPyNumber(pkgOrderList::Added)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_ADD_PENDIG", MkPyNumber(pkgOrderList::AddPending)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_IMMEDIATE", MkPyNumber(pkgOrderList::Immediate)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_LOOP", MkPyNumber(pkgOrderList::Loop)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_UNPACKED", MkPyNumber(pkgOrderList::UnPacked)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_CONFIGURED", MkPyNumber(pkgOrderList::Configured)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_REMOVED", MkPyNumber(pkgOrderList::Removed)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_IN_LIST", MkPyNumber(pkgOrderList::InList)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_AFTER", MkPyNumber(pkgOrderList::After)); + PyDict_SetItemString(PyOrderList_Type.tp_dict, "FLAG_STATES_MASK", MkPyNumber(pkgOrderList::States)); + + // Acquire constants. + // some constants + PyDict_SetItemString(PyAcquire_Type.tp_dict, "RESULT_CANCELLED", + MkPyNumber(pkgAcquire::Cancelled)); + PyDict_SetItemString(PyAcquire_Type.tp_dict, "RESULT_CONTINUE", + MkPyNumber(pkgAcquire::Continue)); + PyDict_SetItemString(PyAcquire_Type.tp_dict, "RESULT_FAILED", + MkPyNumber(pkgAcquire::Failed)); + // Dependency constants + PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_DEPENDS", + MkPyNumber(pkgCache::Dep::Depends)); + PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_PREDEPENDS", + MkPyNumber(pkgCache::Dep::PreDepends)); + PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_SUGGESTS", + MkPyNumber(pkgCache::Dep::Suggests)); + PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_RECOMMENDS", + MkPyNumber(pkgCache::Dep::Recommends)); + PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_CONFLICTS", + MkPyNumber(pkgCache::Dep::Conflicts)); + PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_REPLACES", + MkPyNumber(pkgCache::Dep::Replaces)); + PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_OBSOLETES", + MkPyNumber(pkgCache::Dep::Obsoletes)); + PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_DPKG_BREAKS", + MkPyNumber(pkgCache::Dep::DpkgBreaks)); + PyDict_SetItemString(PyDependency_Type.tp_dict, "TYPE_ENHANCES", + MkPyNumber(pkgCache::Dep::Enhances)); + + + // PackageManager constants + PyDict_SetItemString(PyPackageManager_Type.tp_dict, "RESULT_COMPLETED", + MkPyNumber(pkgPackageManager::Completed)); + PyDict_SetItemString(PyPackageManager_Type.tp_dict, "RESULT_FAILED", + MkPyNumber(pkgPackageManager::Failed)); + PyDict_SetItemString(PyPackageManager_Type.tp_dict, "RESULT_INCOMPLETE", + MkPyNumber(pkgPackageManager::Incomplete)); + + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_NO", + MkPyNumber(pkgCache::Version::No)); + // NONE is deprecated (#782802) + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_NONE", + MkPyNumber(pkgCache::Version::No)); + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_ALL", + MkPyNumber(pkgCache::Version::All)); + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_FOREIGN", + MkPyNumber(pkgCache::Version::Foreign)); + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_SAME", + MkPyNumber(pkgCache::Version::Same)); + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_ALLOWED", + MkPyNumber(pkgCache::Version::Allowed)); + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_ALL_FOREIGN", + MkPyNumber(pkgCache::Version::AllForeign)); + PyDict_SetItemString(PyVersion_Type.tp_dict, "MULTI_ARCH_ALL_ALLOWED", + MkPyNumber(pkgCache::Version::AllAllowed)); + // AcquireItem Constants. + PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_IDLE", + MkPyNumber(pkgAcquire::Item::StatIdle)); + PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_FETCHING", + MkPyNumber(pkgAcquire::Item::StatFetching)); + PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_DONE", + MkPyNumber(pkgAcquire::Item::StatDone)); + PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_TRANSIENT_NETWORK_ERROR", + MkPyNumber(pkgAcquire::Item::StatTransientNetworkError)); + PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_ERROR", + MkPyNumber(pkgAcquire::Item::StatError)); + PyDict_SetItemString(PyAcquireItem_Type.tp_dict, "STAT_AUTH_ERROR", + MkPyNumber(pkgAcquire::Item::StatAuthError)); + // TagSection constants + PyDict_SetItemString(PyTag_Type.tp_dict, "REMOVE", + MkPyNumber(pkgTagSection::Tag::REMOVE)); + PyDict_SetItemString(PyTag_Type.tp_dict, "REWRITE", + MkPyNumber(pkgTagSection::Tag::REWRITE)); + PyDict_SetItemString(PyTag_Type.tp_dict, "RENAME", + MkPyNumber(pkgTagSection::Tag::RENAME)); + +#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 1 + PyObject *PyCapsule = PyCapsule_New(&API, "apt_pkg._C_API", NULL); +#else + PyObject *PyCapsule = PyCObject_FromVoidPtr(&API, NULL); +#endif + PyModule_AddObject(Module, "_C_API", PyCapsule); + // Version.. + PyModule_AddStringConstant(Module,"VERSION",(char *)pkgVersion); + PyModule_AddStringConstant(Module,"LIB_VERSION",(char *)pkgLibVersion); +#ifdef DATE + PyModule_AddStringConstant(Module,"DATE",DATE); + PyModule_AddStringConstant(Module,"TIME",TIME); +#else + PyModule_AddStringConstant(Module,"DATE", "Jan 1 1970"); + PyModule_AddStringConstant(Module,"TIME", "00:00:00"); +#endif + + // My constants + PyModule_AddIntConstant(Module,"PRI_IMPORTANT",pkgCache::State::Important); + PyModule_AddIntConstant(Module,"PRI_REQUIRED",pkgCache::State::Required); + PyModule_AddIntConstant(Module,"PRI_STANDARD",pkgCache::State::Standard); + PyModule_AddIntConstant(Module,"PRI_OPTIONAL",pkgCache::State::Optional); + PyModule_AddIntConstant(Module,"PRI_EXTRA",pkgCache::State::Extra); + // CurState + PyModule_AddIntConstant(Module,"CURSTATE_NOT_INSTALLED",pkgCache::State::NotInstalled); + PyModule_AddIntConstant(Module,"CURSTATE_UNPACKED",pkgCache::State::UnPacked); + PyModule_AddIntConstant(Module,"CURSTATE_HALF_CONFIGURED",pkgCache::State::HalfConfigured); + PyModule_AddIntConstant(Module,"CURSTATE_HALF_INSTALLED",pkgCache::State::HalfInstalled); + PyModule_AddIntConstant(Module,"CURSTATE_CONFIG_FILES",pkgCache::State::ConfigFiles); + PyModule_AddIntConstant(Module,"CURSTATE_INSTALLED",pkgCache::State::Installed); + // SelState + PyModule_AddIntConstant(Module,"SELSTATE_UNKNOWN",pkgCache::State::Unknown); + PyModule_AddIntConstant(Module,"SELSTATE_INSTALL",pkgCache::State::Install); + PyModule_AddIntConstant(Module,"SELSTATE_HOLD",pkgCache::State::Hold); + PyModule_AddIntConstant(Module,"SELSTATE_DEINSTALL",pkgCache::State::DeInstall); + PyModule_AddIntConstant(Module,"SELSTATE_PURGE",pkgCache::State::Purge); + // InstState + PyModule_AddIntConstant(Module,"INSTSTATE_OK",pkgCache::State::Ok); + PyModule_AddIntConstant(Module,"INSTSTATE_REINSTREQ",pkgCache::State::ReInstReq); + PyModule_AddIntConstant(Module,"INSTSTATE_HOLD",pkgCache::State::Hold); + PyModule_AddIntConstant(Module,"INSTSTATE_HOLD_REINSTREQ",pkgCache::State::HoldReInstReq); + + #if PY_MAJOR_VERSION >= 3 + return Module; + #endif +} + /*}}}*/ + diff --git a/python/apt_pkgmodule.h b/python/apt_pkgmodule.h new file mode 100644 index 0000000..ee92c50 --- /dev/null +++ b/python/apt_pkgmodule.h @@ -0,0 +1,214 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: apt_pkgmodule.h,v 1.4 2003/07/23 02:20:24 mdz Exp $ +/* ###################################################################### + + Prototypes for the module + + ##################################################################### */ + /*}}}*/ +#ifndef APT_PKGMODULE_H +#define APT_PKGMODULE_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "generic.h" + +// Configuration Stuff +extern PyTypeObject PyConfiguration_Type; +extern PyTypeObject PyVersion_Type; + +extern char *doc_LoadConfig; +extern char *doc_LoadConfigISC; +extern char *doc_LoadConfigDir; +extern char *doc_ParseCommandLine; +PyObject *LoadConfig(PyObject *Self,PyObject *Args); +PyObject *LoadConfigISC(PyObject *Self,PyObject *Args); +PyObject *LoadConfigDir(PyObject *Self,PyObject *Args); +PyObject *ParseCommandLine(PyObject *Self,PyObject *Args); + +// Tag File Stuff +extern PyTypeObject PyTagSection_Type; +extern PyTypeObject PyTagFile_Type; +extern PyTypeObject PyTag_Type; +extern PyTypeObject PyTagRewrite_Type; +extern PyTypeObject PyTagRename_Type; +extern PyTypeObject PyTagRemove_Type; +extern char *doc_ParseSection; +extern char *doc_ParseTagFile; +PyObject *ParseSection(PyObject *self,PyObject *Args); +PyObject *ParseTagFile(PyObject *self,PyObject *Args); + +// String Stuff +PyObject *StrQuoteString(PyObject *self,PyObject *Args); +PyObject *StrDeQuote(PyObject *self,PyObject *Args); +PyObject *StrSizeToStr(PyObject *self,PyObject *Args); +PyObject *StrTimeToStr(PyObject *self,PyObject *Args); +PyObject *StrURItoFileName(PyObject *self,PyObject *Args); +PyObject *StrBase64Encode(PyObject *self,PyObject *Args); +PyObject *StrStringToBool(PyObject *self,PyObject *Args); +PyObject *StrTimeRFC1123(PyObject *self,PyObject *Args); +PyObject *StrStrToTime(PyObject *self,PyObject *Args); +PyObject *StrCheckDomainList(PyObject *Self,PyObject *Args); + +PyObject *PyAcquire_GetItem(PyObject *self, pkgAcquire::Item *item); +PyObject *PyAcquire_GetItemDesc(PyObject *self, pkgAcquire::ItemDesc *item); +bool PyAcquire_DropItem(PyObject *self, pkgAcquire::Item *item); + +// Cache Stuff +extern PyTypeObject PyCache_Type; +extern PyTypeObject PyCacheFile_Type; +extern PyTypeObject PyPackageList_Type; +extern PyTypeObject PyDescription_Type; +extern PyTypeObject PyGroup_Type; +extern PyTypeObject PyGroupList_Type; /* internal */ +extern PyTypeObject PyPackage_Type; +extern PyTypeObject PyPackageFile_Type; +extern PyTypeObject PyDependency_Type; +extern PyTypeObject PyDependencyList_Type; +PyObject *TmpGetCache(PyObject *Self,PyObject *Args); + +// DepCache +extern PyTypeObject PyDepCache_Type; +PyObject *GetDepCache(PyObject *Self,PyObject *Args); + +// pkgProblemResolver +extern PyTypeObject PyProblemResolver_Type; +PyObject *GetPkgProblemResolver(PyObject *Self, PyObject *Args); +PyObject *GetPkgActionGroup(PyObject *Self, PyObject *Args); + +extern PyTypeObject PyActionGroup_Type; +// cdrom +extern PyTypeObject PyCdrom_Type; +PyObject *GetCdrom(PyObject *Self,PyObject *Args); + +// acquire +extern PyTypeObject PyAcquireItem_Type; +extern PyTypeObject PyAcquire_Type; +extern PyTypeObject PyAcquireFile_Type; +extern char *doc_GetPkgAcqFile; +PyObject *GetAcquire(PyObject *Self,PyObject *Args); +PyObject *GetPkgAcqFile(PyObject *Self, PyObject *Args, PyObject *kwds); + +// packagemanager +extern PyTypeObject PyPackageManager_Type; +extern PyTypeObject PyPackageManager2_Type; +PyObject *GetPkgManager(PyObject *Self,PyObject *Args); + + +// PkgRecords Stuff +extern PyTypeObject PyPackageRecords_Type; +extern PyTypeObject PySourceRecords_Type; +extern PyTypeObject PySourceRecordFiles_Type; +PyObject *GetPkgRecords(PyObject *Self,PyObject *Args); +PyObject *GetPkgSrcRecords(PyObject *Self,PyObject *Args); + +// pkgSourceList +extern PyTypeObject PySourceList_Type; +PyObject *GetPkgSourceList(PyObject *Self,PyObject *Args); + +// pkgSourceList +extern PyTypeObject PyIndexFile_Type; + +// metaIndex +extern PyTypeObject PyMetaIndex_Type; + +// HashString +extern PyTypeObject PyHashString_Type; + +extern PyTypeObject PyHashStringList_Type; + + +// Policy +extern PyTypeObject PyPolicy_Type; +extern PyTypeObject PyHashes_Type; +extern PyTypeObject PyAcquireItemDesc_Type; +extern PyTypeObject PyAcquireWorker_Type; +extern PyTypeObject PySystemLock_Type; +extern PyTypeObject PyFileLock_Type; +extern PyTypeObject PyOrderList_Type; + +// Functions to be exported in the public API. + +# define PyAcquire_ToCpp GetCpp +# define PyAcquireFile_ToCpp GetCpp +# define PyAcquireItem_ToCpp GetCpp +# define PyAcquireItemDesc_ToCpp GetCpp +# define PyAcquireWorker_ToCpp GetCpp +# define PyActionGroup_ToCpp GetCpp +# define PyCache_ToCpp GetCpp +# define PyCacheFile_ToCpp GetCpp +# define PyCdrom_ToCpp GetCpp +# define PyConfiguration_ToCpp GetCpp +# define PyDepCache_ToCpp GetCpp +# define PyDependency_ToCpp GetCpp +# define PyDependencyList_ToCpp GetCpp // TODO +# define PyDescription_ToCpp GetCpp +# define PyGroup_ToCpp GetCpp +# define PyHashes_ToCpp GetCpp +# define PyHashString_ToCpp GetCpp +# define PyMetaIndex_ToCpp GetCpp +# define PyPackage_ToCpp GetCpp +# define PyPackageFile_ToCpp GetCpp +# define PyIndexFile_ToCpp GetCpp +# define PyOrderList_ToCpp GetCpp +# define PyPackageList_ToCpp GetCpp // TODO +# define PyPackageManager_ToCpp GetCpp +# define PyPackageRecords_ToCpp GetCpp // TODO +# define PyPolicy_ToCpp GetCpp +# define PyProblemResolver_ToCpp GetCpp +# define PySourceList_ToCpp GetCpp +# define PySourceRecords_ToCpp GetCpp // TODO +# define PyTagFile_ToCpp GetCpp +# define PyTagSection_ToCpp GetCpp +# define PyVersion_ToCpp GetCpp + +PyObject* PyAcquire_FromCpp(pkgAcquire *fetcher, bool Delete, PyObject *Owner); +PyObject* PyAcquireFile_FromCpp(pkgAcqFile* const &obj, bool Delete, PyObject *Owner); +PyObject* PyAcquireItem_FromCpp(pkgAcquire::Item* const &obj, bool Delete, PyObject *Owner); +PyObject* PyAcquireItemDesc_FromCpp(pkgAcquire::ItemDesc* const &obj, bool Delete, PyObject *Owner); +PyObject* PyAcquireWorker_FromCpp(pkgAcquire::Worker* const &obj, bool Delete, PyObject *Owner); +PyObject* PyActionGroup_FromCpp(pkgDepCache::ActionGroup* const &obj, bool Delete, PyObject *Owner); +PyObject* PyCache_FromCpp(pkgCache* const &obj, bool Delete, PyObject *Owner); +PyObject* PyCacheFile_FromCpp(pkgCacheFile* const &obj, bool Delete, PyObject *Owner); +PyObject* PyCdrom_FromCpp(pkgCdrom const &obj, bool Delete, PyObject *Owner); +PyObject* PyConfiguration_FromCpp(Configuration* const &obj, bool Delete, PyObject *Owner); +PyObject* PyDepCache_FromCpp(pkgDepCache* const &obj, bool Delete, PyObject *Owner); +PyObject* PyDependency_FromCpp(pkgCache::DepIterator const &obj, bool Delete, PyObject *Owner); +//PyObject* PyDependencyList_FromCpp(RDepListStruct const &obj, bool Delete, PyObject *Owner); +PyObject* PyDescription_FromCpp(pkgCache::DescIterator const &obj, bool Delete, PyObject *Owner); +PyObject* PyHashes_FromCpp(Hashes const &obj, bool Delete, PyObject *Owner); +PyObject* PyHashString_FromCpp(HashString* const &obj, bool Delete, PyObject *Owner); +PyObject* PyMetaIndex_FromCpp(metaIndex* const &obj, bool Delete, PyObject *Owner); +PyObject* PyPackage_FromCpp(pkgCache::PkgIterator const &obj, bool Delete, PyObject *Owner); +PyObject* PyGroup_FromCpp(pkgCache::GrpIterator const &obj, bool Delete, PyObject *Owner); +PyObject* PyIndexFile_FromCpp(pkgIndexFile* const &obj, bool Delete, PyObject *Owner); +PyObject* PyOrderList_FromCpp(pkgOrderList* const &obj, bool Delete, PyObject *Owner); +PyObject* PyPackageFile_FromCpp(pkgCache::PkgFileIterator const &obj, bool Delete, PyObject *Owner); +//PyObject* PyPackageList_FromCpp(PkgListStruct const &obj, bool Delete, PyObject *Owner); +PyObject* PyPackageManager_FromCpp(pkgPackageManager* const &obj, bool Delete, PyObject *Owner); +//PyObject* PyPackageRecords_FromCpp(PkgRecordsStruct const &obj, bool Delete, PyObject *Owner); +PyObject* PyPolicy_FromCpp(pkgPolicy* const &obj, bool Delete, PyObject *Owner); +PyObject* PyProblemResolver_FromCpp(pkgProblemResolver* const &obj, bool Delete, PyObject *Owner); +PyObject* PySourceList_FromCpp(pkgSourceList* const &obj, bool Delete, PyObject *Owner); +//PyObject* PySourceRecords_FromCpp(PkgSrcRecordsStruct const &obj, bool Delete, PyObject *Owner); +PyObject* PyTagFile_FromCpp(pkgTagFile const &obj, bool Delete, PyObject *Owner); +PyObject* PyTagSection_FromCpp(pkgTagSection const &obj, bool Delete, PyObject *Owner); +PyObject* PyVersion_FromCpp(pkgCache::VerIterator const &obj, bool Delete, PyObject *Owner); + +#include "python-apt.h" +#endif + diff --git a/python/arfile.cc b/python/arfile.cc new file mode 100644 index 0000000..8f623b3 --- /dev/null +++ b/python/arfile.cc @@ -0,0 +1,744 @@ +/* + * arfile.cc - Wrapper around ARArchive and ARArchive::Member. + * + * Copyright 2009 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include "generic.h" +#include "apt_instmodule.h" +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +static PyObject *armember_get_name(PyObject *self, void *closure) +{ + return CppPyPath(GetCpp(self)->Name); +} + +static PyObject *armember_get_mtime(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self)->MTime); +} + +static PyObject *armember_get_uid(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self)->UID); +} + +static PyObject *armember_get_gid(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self)->GID); +} + +static PyObject *armember_get_mode(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self)->Mode); +} + +static PyObject *armember_get_size(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self)->Size); +} + +static PyObject *armember_get_start(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self)->Start); +} + +static PyObject *armember_repr(PyObject *self) +{ + return PyString_FromFormat("<%s object: name:'%s'>", + self->ob_type->tp_name, + GetCpp(self)->Name.c_str()); +} + +static PyGetSetDef armember_getset[] = { + {"gid",armember_get_gid,0,"The group id of the owner."}, + {"mode",armember_get_mode,0,"The mode of the file."}, + {"mtime",armember_get_mtime,0,"Last time of modification."}, + {"name",armember_get_name,0,"The name of the file."}, + {"size",armember_get_size,0,"The size of the files."}, + {"start",armember_get_start,0, + "The offset in the archive where the file starts."}, + {"uid",armember_get_uid,0,"The user ID of the owner."}, + {NULL} +}; + +static const char *armember_doc = + "Represent a single file within an AR archive. For\n" + "Debian packages this can be e.g. control.tar.gz. This class provides\n" + "information about this file, such as the mode and size."; +PyTypeObject PyArMember_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_inst.ArMember", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + armember_repr, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_HAVE_GC, + armember_doc, // tp_doc + CppTraverse,// tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + armember_getset, // tp_getset +}; + + +static const char *filefd_doc= + "Internal helper type, representing a FileFd."; +PyTypeObject PyFileFd_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_inst.__FileFd" , // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_HAVE_GC, + filefd_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear +}; + + +// We just add an inline method and should thus be ABI compatible in a way that +// we can simply cast ARArchive instances to PyARArchiveHack. +class PyARArchiveHack : public ARArchive +{ +public: + inline Member *Members() { + return List; + } +}; + +struct PyArArchiveObject : public CppPyObject { + CppPyObject *Fd; +}; + +static const char *ararchive_getmember_doc = + "getmember(name: str) -> ArMember\n\n" + "Return an ArMember object for the member given by 'name'. Raise\n" + "LookupError if there is no ArMember with the given name."; +static PyObject *ararchive_getmember(PyArArchiveObject *self, PyObject *arg) +{ + PyApt_Filename name; + CppPyObject *ret; + if (!name.init(arg)) + return 0; + + const ARArchive::Member *member = self->Object->FindMember(name); + if (!member) { + PyErr_Format(PyExc_LookupError,"No member named '%s'",name.path); + return 0; + } + + // Create our object. + ret = CppPyObject_NEW(self,&PyArMember_Type); + ret->Object = const_cast(member); + ret->NoDelete = true; + return ret; +} + +static const char *ararchive_extractdata_doc = + "extractdata(name: str) -> bytes\n\n" + "Return the contents of the member, as a bytes object. Raise\n" + "LookupError if there is no ArMember with the given name."; +static PyObject *ararchive_extractdata(PyArArchiveObject *self, PyObject *args) +{ + PyApt_Filename name; + if (PyArg_ParseTuple(args, "O&:extractdata", PyApt_Filename::Converter, &name) == 0) + return 0; + const ARArchive::Member *member = self->Object->FindMember(name); + if (!member) { + PyErr_Format(PyExc_LookupError,"No member named '%s'",name.path); + return 0; + } + if (member->Size > SIZE_MAX) { + PyErr_Format(PyExc_MemoryError, + "Member '%s' is too large to read into memory",name.path); + return 0; + } + if (!self->Fd->Object.Seek(member->Start)) + return HandleErrors(); + + char* value; + try { + value = new char[member->Size]; + } catch (std::bad_alloc&) { + PyErr_Format(PyExc_MemoryError, + "Member '%s' is too large to read into memory",name.path); + return 0; + } + self->Fd->Object.Read(value, member->Size, true); + PyObject *result = PyBytes_FromStringAndSize(value, member->Size); + delete[] value; + return result; +} + +// Helper class to close the FD automatically. +class IntFD { + public: + int fd; + inline operator int() { return fd; }; + inline IntFD(int fd): fd(fd) { }; + inline ~IntFD() { close(fd); }; +}; + +static PyObject *_extract(FileFd &Fd, const ARArchive::Member *member, + const char *dir) +{ + if (!Fd.Seek(member->Start)) + return HandleErrors(); + + std::string outfile_str = flCombine(dir,member->Name); + char *outfile = (char*)outfile_str.c_str(); + + // We are not using FileFd here, because we want to raise OSErrror with + // the correct errno and filename. IntFD's are closed automatically. + IntFD outfd(open(outfile, O_NDELAY|O_WRONLY|O_CREAT|O_TRUNC|O_APPEND, + member->Mode)); + if (outfd == -1) + return PyErr_SetFromErrnoWithFilename(PyExc_OSError, outfile); + if (fchmod(outfd, member->Mode) == -1) + return PyErr_SetFromErrnoWithFilename(PyExc_OSError, outfile); + if (fchown(outfd, member->UID, member->GID) != 0 && errno != EPERM) + return PyErr_SetFromErrnoWithFilename(PyExc_OSError, outfile); + + // Read 4 KiB from the file, until all of the file is read. Deallocated + // automatically when the function returns. + std::array value; + unsigned long long size = member->Size; + unsigned long long read = 4096; + while (size > 0) { + if (size < read) + read = size; + if (!Fd.Read(value.data(), read, true)) + return HandleErrors(); + if (write(outfd, value.data(), read) != (signed long long)read) + return PyErr_SetFromErrnoWithFilename(PyExc_OSError, outfile); + size -= read; + } + utimbuf time = {static_cast(member->MTime), + static_cast(member->MTime)}; + if (utime(outfile,&time) == -1) + return PyErr_SetFromErrnoWithFilename(PyExc_OSError, outfile); + Py_RETURN_TRUE; +} + +static const char *ararchive_extract_doc = + "extract(name: str[, target: str]) -> bool\n\n" + "Extract the member given by 'name' into the directory given\n" + "by 'target'. If the extraction fails, raise OSError. In case\n" + "of success, return True if the file owner could be set or\n" + "False if this was not possible. If the requested member\n" + "does not exist, raise LookupError."; +static PyObject *ararchive_extract(PyArArchiveObject *self, PyObject *args) +{ + PyApt_Filename name; + PyApt_Filename target; + + target = ""; + if (PyArg_ParseTuple(args, "O&|O&:extract", PyApt_Filename::Converter, &name, PyApt_Filename::Converter, &target) == 0) + return 0; + + const ARArchive::Member *member = self->Object->FindMember(name); + + if (!member) { + PyErr_Format(PyExc_LookupError,"No member named '%s'",name.path); + return 0; + } + return _extract(self->Fd->Object, member, target); +} + +static const char *ararchive_extractall_doc = + "extractall([target: str]) -> bool\n\n" + "Extract all archive contents into the directory given by 'target'. If\n" + "the extraction fails, raise an error. Otherwise, return True if the\n" + "owner could be set or False if the owner could not be changed."; + +static PyObject *ararchive_extractall(PyArArchiveObject *self, PyObject *args) +{ + PyApt_Filename target; + target = ""; + if (PyArg_ParseTuple(args, "|O&:extractall", PyApt_Filename::Converter, &target) == 0) + return 0; + + const ARArchive::Member *member = self->Object->Members(); + + do { + if (_extract(self->Fd->Object, member, target) == 0) + return 0; + } while ((member = member->Next)); + Py_RETURN_TRUE; +} + +static const char *ararchive_gettar_doc = + "gettar(name: str, comp: str) -> TarFile\n\n" + "Return a TarFile object for the member given by 'name' which will be\n" + "decompressed using the compression algorithm given by 'comp'.\n" + "This is almost equal to:\n\n" + " member = arfile.getmember(name)\n" + " tarfile = TarFile(file, member.start, member.size, 'gzip')'\n\n" + "It just opens a new TarFile on the given position in the stream."; +static PyObject *ararchive_gettar(PyArArchiveObject *self, PyObject *args) +{ + PyApt_Filename name; + const char *comp; + if (PyArg_ParseTuple(args, "O&s:gettar", PyApt_Filename::Converter, &name, &comp) == 0) + return 0; + + const ARArchive::Member *member = self->Object->FindMember(name); + if (!member) { + PyErr_Format(PyExc_LookupError,"No member named '%s'",name.path); + return 0; + } + + PyTarFileObject *tarfile = (PyTarFileObject*)CppPyObject_NEW(self->Fd,&PyTarFile_Type); + new (&tarfile->Fd) FileFd(self->Fd->Object.Fd()); + tarfile->min = member->Start; + tarfile->Object = new ExtractTar(self->Fd->Object, member->Size, comp); + return HandleErrors(tarfile); +} + +static const char *ararchive_getmembers_doc = + "getmembers() -> list\n\n" + "Return a list of all members in the archive."; +static PyObject *ararchive_getmembers(PyArArchiveObject *self) +{ + PyObject *list = PyList_New(0); + ARArchive::Member *member = self->Object->Members(); + do { + CppPyObject *ret; + ret = CppPyObject_NEW(self,&PyArMember_Type); + ret->Object = member; + ret->NoDelete = true; + PyList_Append(list, ret); + Py_DECREF(ret); + } while ((member = member->Next)); + return list; +} + +static const char *ararchive_getnames_doc = + "getnames() -> list\n\n" + "Return a list of the names of all members in the archive."; +static PyObject *ararchive_getnames(PyArArchiveObject *self) +{ + PyObject *list = PyList_New(0); + ARArchive::Member *member = self->Object->Members(); + do { + PyObject *item = CppPyString(member->Name); + PyList_Append(list, item); + Py_DECREF(item); + } while ((member = member->Next)); + return list; +} + +// Just run getmembers() and return an iterator over the list. +static PyObject *ararchive_iter(PyArArchiveObject *self) { + PyObject *members = ararchive_getmembers(self); + PyObject *iter = PyObject_GetIter(members); + Py_DECREF(members); + return iter; +} + +static PyMethodDef ararchive_methods[] = { + {"getmember",(PyCFunction)ararchive_getmember,METH_O, + ararchive_getmember_doc}, + {"gettar",(PyCFunction)ararchive_gettar,METH_VARARGS, + ararchive_gettar_doc}, + {"extractdata",(PyCFunction)ararchive_extractdata,METH_VARARGS, + ararchive_extractdata_doc}, + {"extract",(PyCFunction)ararchive_extract,METH_VARARGS, + ararchive_extract_doc}, + {"extractall",(PyCFunction)ararchive_extractall,METH_VARARGS, + ararchive_extractall_doc}, + {"getmembers",(PyCFunction)ararchive_getmembers,METH_NOARGS, + ararchive_getmembers_doc}, + {"getnames",(PyCFunction)ararchive_getnames,METH_NOARGS, + ararchive_getnames_doc}, + {NULL} +}; + +static PyObject *ararchive_new(PyTypeObject *type, PyObject *args, + PyObject *kwds) +{ + PyObject *file; + PyApt_Filename filename; + int fileno; + if (PyArg_ParseTuple(args,"O:__new__",&file) == 0) + return 0; + + PyApt_UniqueObject self(NULL); + // We receive a filename. + if (filename.init(file)) { + self.reset((PyArArchiveObject*) CppPyObject_NEW(0,type)); + self->Fd = CppPyObject_NEW(NULL, &PyFileFd_Type); + new (&self->Fd->Object) FileFd(filename,FileFd::ReadOnly); + } + // We receive a file object. + else if ((fileno = PyObject_AsFileDescriptor(file)) != -1) { + // Clear the error set by PyObject_AsString(). + PyErr_Clear(); + self.reset((PyArArchiveObject*) CppPyObject_NEW(NULL,type)); + self->Fd = CppPyObject_NEW(file, &PyFileFd_Type); + new (&self->Fd->Object) FileFd(fileno,false); + } + else { + return 0; + } + self->Object = (PyARArchiveHack*)new ARArchive(self->Fd->Object); + if (_error->PendingError() == true) + return HandleErrors(); + return self.release(); +} + +static int ararchive_traverse(PyObject *_self, visitproc visit, void* arg) +{ + PyArArchiveObject *self = (PyArArchiveObject*)_self; + Py_VISIT(self->Fd); + return CppTraverse(self, visit, arg); +} + +static int ararchive_clear(PyObject *_self) +{ + PyArArchiveObject *self = (PyArArchiveObject*)_self; + Py_CLEAR(self->Fd); + return CppClear(self); +} + +static void ararchive_dealloc(PyObject *self) +{ + ararchive_clear(self); + CppDeallocPtr(self); +} + +// Return bool or -1 (exception). +static int ararchive_contains(PyObject *self, PyObject *arg) +{ + PyApt_Filename name; + if (!name.init(arg)) + return -1; + return (GetCpp(self)->FindMember(name) != 0); +} + +static PySequenceMethods ararchive_as_sequence = { + 0,0,0,0,0,0,0,ararchive_contains,0,0 +}; + +static PyMappingMethods ararchive_as_mapping = { + 0,(PyCFunction)ararchive_getmember,0 +}; + +static const char *ararchive_doc = + "ArArchive(file: str/int/file)\n\n" + "Represent an archive in the 4.4 BSD ar format,\n" + "which is used for e.g. deb packages.\n\n" + "The parameter 'file' may be a string specifying the path of a file, or\n" + "a file-like object providing the fileno() method. It may also be an int\n" + "specifying a file descriptor (returned by e.g. os.open()).\n" + "The recommended way of using it is to pass in the path to the file."; + +PyTypeObject PyArArchive_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_inst.ArArchive", // tp_name + sizeof(PyArArchiveObject), // tp_basicsize + 0, // tp_itemsize + // Methods + ararchive_dealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &ararchive_as_sequence, // tp_as_sequence + &ararchive_as_mapping, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_HAVE_GC, + ararchive_doc, // tp_doc + ararchive_traverse, // tp_traverse + ararchive_clear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + (getiterfunc)ararchive_iter, // tp_iter + 0, // tp_iternext + ararchive_methods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + ararchive_new // tp_new +}; + +/** + * Representation of a Debian package. + * + * This does not resemble debDebFile in apt-inst, but instead is a subclass + * of ArFile which adds properties for the control.tar.$compression and + * data.tar.$compression members which return TarFile objects. It also adds + * a descriptor 'version' which returns the content of 'debian-binary'. + * + * We are using it this way as it seems more natural to represent this special + * kind of AR archive as an AR archive with some extras. + */ +struct PyDebFileObject : PyArArchiveObject { + PyObject *data; + PyObject *control; + PyObject *debian_binary; +}; + +static PyObject *debfile_get_data(PyDebFileObject *self) +{ + return Py_INCREF(self->data), self->data; +} + +static PyObject *debfile_get_control(PyDebFileObject *self) +{ + return Py_INCREF(self->control), self->control; +} + +static PyObject *debfile_get_debian_binary(PyDebFileObject *self) +{ + return Py_INCREF(self->debian_binary), self->debian_binary; +} + +static PyObject *_gettar(PyDebFileObject *self, const ARArchive::Member *m, + const char *comp) +{ + if (!m) + return 0; + PyTarFileObject *tarfile = (PyTarFileObject*)CppPyObject_NEW(self->Fd,&PyTarFile_Type); + new (&tarfile->Fd) FileFd(self->Fd->Object.Fd()); + tarfile->min = m->Start; + tarfile->Object = new ExtractTar(self->Fd->Object, m->Size, comp); + return tarfile; +} + +/* + * Mostly copy-paste from APT + */ +static PyObject *debfile_get_tar(PyDebFileObject *self, const char *Name) +{ + // Get the archive member + const ARArchive::Member *Member = NULL; + const ARArchive &AR = *self->Object; + std::string Compressor; + + std::vector compressor = + APT::Configuration::getCompressors(); + for (std::vector::const_iterator c = + compressor.begin(); c != compressor.end(); ++c) { + Member = AR.FindMember(std::string(Name).append(c->Extension).c_str()); + if (Member == NULL) + continue; + Compressor = c->Name; + break; + } + + if (Member == NULL) + Member = AR.FindMember(std::string(Name).c_str()); + + if (Member == NULL) { + std::string ext = std::string(Name) + ".{"; + for (std::vector::const_iterator c = + compressor.begin(); c != compressor.end(); ++c) { + if (!c->Extension.empty()) + ext.append(c->Extension.substr(1)); + } + ext.append("}"); + _error->Error(("Internal error, could not locate member %s"), + ext.c_str()); + return HandleErrors(); + } + + return _gettar(self, Member, Compressor.c_str()); +} + + +static PyObject *debfile_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyApt_UniqueObject self((PyDebFileObject*)ararchive_new(type, args, kwds)); + if (self == NULL) + return NULL; + + // DebFile + self->control = debfile_get_tar(self.get(), "control.tar"); + if (self->control == NULL) + return NULL; + + self->data = debfile_get_tar(self.get(), "data.tar"); + if (self->data == NULL) + return NULL; + + const ARArchive::Member *member = self->Object->FindMember("debian-binary"); + if (!member) + return PyErr_Format(PyAptError, "No debian archive, missing %s", + "debian-binary"); + + if (!self->Fd->Object.Seek(member->Start)) + return HandleErrors(); + + char* value = new char[member->Size]; + self->Fd->Object.Read(value, member->Size, true); + self->debian_binary = PyBytes_FromStringAndSize(value, member->Size); + delete[] value; + return self.release(); +} + +static int debfile_traverse(PyObject *_self, visitproc visit, void* arg) +{ + PyDebFileObject *self = (PyDebFileObject*)_self; + Py_VISIT(self->data); + Py_VISIT(self->control); + Py_VISIT(self->debian_binary); + return PyArArchive_Type.tp_traverse(self, visit, arg); +} + +static int debfile_clear(PyObject *_self) { + PyDebFileObject *self = (PyDebFileObject*)_self; + Py_CLEAR(self->data); + Py_CLEAR(self->control); + Py_CLEAR(self->debian_binary); + return PyArArchive_Type.tp_clear(self); +} + +static void debfile_dealloc(PyObject *self) { + debfile_clear((PyDebFileObject *)self); + PyArArchive_Type.tp_dealloc(self); +} + +static PyGetSetDef debfile_getset[] = { + {"control",(getter)debfile_get_control,0, + "The TarFile object associated with the control.tar.gz member."}, + {"data",(getter)debfile_get_data,0, + "The TarFile object associated with the data.tar.$compression member. " + "All apt compression methods are supported. " + }, + {"debian_binary",(getter)debfile_get_debian_binary,0, + "The package version, as contained in debian-binary."}, + {NULL} +}; + +static const char *debfile_doc = + "DebFile(file: str/int/file)\n\n" + "A DebFile object represents a file in the .deb package format.\n\n" + "The parameter 'file' may be a string specifying the path of a file, or\n" + "a file-like object providing the fileno() method. It may also be an int\n" + "specifying a file descriptor (returned by e.g. os.open()).\n" + "The recommended way of using it is to pass in the path to the file.\n\n" + "It differs from ArArchive by providing the members 'control', 'data'\n" + "and 'version' for accessing the control.tar.gz, data.tar.$compression \n" + "(all apt compression methods are supported), and debian-binary members \n" + "in the archive."; + +PyTypeObject PyDebFile_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_inst.DebFile", // tp_name + sizeof(PyDebFileObject), // tp_basicsize + 0, // tp_itemsize + // Methods + debfile_dealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_HAVE_GC, + debfile_doc, // tp_doc + debfile_traverse, // tp_traverse + debfile_clear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + debfile_getset, // tp_getset + &PyArArchive_Type, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + debfile_new // tp_new +}; diff --git a/python/cache.cc b/python/cache.cc new file mode 100644 index 0000000..81bbb96 --- /dev/null +++ b/python/cache.cc @@ -0,0 +1,1600 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cache.cc,v 1.5 2003/06/03 03:03:23 mdz Exp $ +/* ###################################################################### + + Cache - Wrapper for the cache related functions + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "generic.h" +#include "apt_pkgmodule.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "progress.h" + +class pkgSourceList; + +// must be in sync with pkgCache::DepType in libapt +// it sucks to have it here duplicated, but we get it +// translated from libapt and that is certainly not what +// we want in a programing interface +const char *UntranslatedDepTypes[] = +{ + "", "Depends","PreDepends","Suggests", + "Recommends","Conflicts","Replaces", + "Obsoletes", "Breaks", "Enhances" +}; + + /*}}}*/ + +template struct IterListStruct +{ + T Iter; + unsigned long LastIndex; + + IterListStruct(T const &I) : Iter(I), LastIndex(0) {} + IterListStruct() : LastIndex(0) {}; + + bool move(unsigned long Index) { + if ((unsigned)Index >= Count()) + { + PyErr_SetNone(PyExc_IndexError); + return false; + } + + if ((unsigned)Index < LastIndex) + { + LastIndex = 0; + Iter = Begin(); + } + + while ((unsigned)Index > LastIndex) + { + LastIndex++; + Iter++; + if (Iter.end() == true) + { + PyErr_SetNone(PyExc_IndexError); + return false; + } + } + return true; + } + + virtual unsigned Count() = 0; + virtual T Begin() = 0; + +}; + +struct PkgListStruct : public IterListStruct { + unsigned Count() { return Iter.Cache()->HeaderP->PackageCount; } + pkgCache::PkgIterator Begin() { return Iter.Cache()->PkgBegin(); } + + PkgListStruct(pkgCache::PkgIterator const &I) { Iter = I; } +}; + +struct GrpListStruct : public IterListStruct { + unsigned Count() { return Iter.Cache()->HeaderP->GroupCount; } + pkgCache::GrpIterator Begin() { return Iter.Cache()->GrpBegin(); } + GrpListStruct(pkgCache::GrpIterator const &I) { Iter = I; } +}; + +struct RDepListStruct +{ + pkgCache::DepIterator Iter; + pkgCache::DepIterator Start; + unsigned long LastIndex; + unsigned long Len; + + RDepListStruct(pkgCache::DepIterator const &I) : Iter(I), Start(I), + LastIndex(0) + { + Len = 0; + pkgCache::DepIterator D = I; + for (; D.end() == false; D++) + Len++; + } + RDepListStruct() {abort();}; // G++ Bug.. +}; + +static PyObject *CreateProvides(PyObject *Owner,pkgCache::PrvIterator I) +{ + PyObject *List = PyList_New(0); + for (; I.end() == false; I++) + { + PyObject *Obj; + PyObject *Ver; + Ver = CppPyObject_NEW(Owner,&PyVersion_Type, + I.OwnerVer()); + Obj = Py_BuildValue("ssN",I.ParentPkg().Name(),I.ProvideVersion(), + Ver); + PyList_Append(List,Obj); + Py_DECREF(Obj); + } + return List; +} + +// Cache Class /*{{{*/ +// --------------------------------------------------------------------- + +static const char *cache_update_doc = + "update(progress, sources: SourceList, pulse_interval: int) -> bool\n\n" + "Update the index files used by the cache. A call to this method\n" + "does not affect the current Cache object; instead, a new one\n" + "should be created in order to use the changed index files.\n\n" + "The parameter 'progress' can be used to specify an\n" + "apt.progress.base.AcquireProgress() object , which will report\n" + "progress information while the index files are being fetched.\n" + "The parameter 'sources', if provided, is an apt_pkg.SourcesList\n" + "object listing the remote repositories to be used.\n" + "The 'pulse_interval' parameter indicates how long (in microseconds)\n" + "to wait between calls to the pulse() method of the 'progress' object.\n" + "The default is 500000 microseconds."; +static PyObject *PkgCacheUpdate(PyObject *Self,PyObject *Args) +{ + PyObject *pyFetchProgressInst = 0; + PyObject *pySourcesList = 0; + int pulseInterval = 0; + if (PyArg_ParseTuple(Args, "OO!|i", &pyFetchProgressInst, + &PySourceList_Type, &pySourcesList, &pulseInterval) == 0) + return 0; + + PyFetchProgress progress; + progress.setCallbackInst(pyFetchProgressInst); + pkgSourceList *source = GetCpp(pySourcesList); + bool res = ListUpdate(progress, *source, pulseInterval); + + PyObject *PyRes = PyBool_FromLong(res); + return HandleErrors(PyRes); +} + + +static PyMethodDef PkgCacheMethods[] = +{ + {"update",PkgCacheUpdate,METH_VARARGS,cache_update_doc}, + {} +}; + +static PyObject *PkgCacheGetGroupCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + return MkPyNumber(Cache->HeaderP->GroupCount); +} + +static PyObject *PkgCacheGetGroups(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + return CppPyObject_NEW(Self,&PyGroupList_Type,Cache->GrpBegin()); +} + +static PyObject *PkgCacheGetPolicy(PyObject *Self, void*) { + PyObject *CacheFilePy = GetOwner(Self); + pkgCacheFile *CacheF = GetCpp(CacheFilePy); + pkgDepCache *DepCache = (pkgDepCache *)(*CacheF); + + pkgPolicy *Policy = (pkgPolicy *)&DepCache->GetPolicy(); + CppPyObject *PyPolicy = + CppPyObject_NEW(Self,&PyPolicy_Type,Policy); + // Policy should not be deleted, it is managed by CacheFile. + PyPolicy->NoDelete = true; + return PyPolicy; +} + +static PyObject *PkgCacheGetPackages(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + return CppPyObject_NEW(Self,&PyPackageList_Type,Cache->PkgBegin()); +} + +static PyObject *PkgCacheGetPackageCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + return MkPyNumber((int)Cache->HeaderP->PackageCount); +} + +static PyObject *PkgCacheGetVersionCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + return MkPyNumber(Cache->HeaderP->VersionCount); +} +static PyObject *PkgCacheGetDependsCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + return MkPyNumber(Cache->HeaderP->DependsCount); +} + +static PyObject *PkgCacheGetPackageFileCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + return MkPyNumber(Cache->HeaderP->PackageFileCount); +} + +static PyObject *PkgCacheGetVerFileCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + return MkPyNumber(Cache->HeaderP->VerFileCount); +} + +static PyObject *PkgCacheGetProvidesCount(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + return MkPyNumber(Cache->HeaderP->ProvidesCount); +} + +static PyObject *PkgCacheGetFileList(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + PyObject *List = PyList_New(0); + for (pkgCache::PkgFileIterator I = Cache->FileBegin(); I.end() == false; I++) + { + PyObject *Obj; + Obj = CppPyObject_NEW(Self,&PyPackageFile_Type,I); + PyList_Append(List,Obj); + Py_DECREF(Obj); + } + return List; +} + +static PyObject *PkgCacheGetIsMultiArch(PyObject *Self, void*) { + pkgCache *Cache = GetCpp(Self); + return PyBool_FromLong(Cache->MultiArchCache()); +} + +static PyGetSetDef PkgCacheGetSet[] = { + {"depends_count",PkgCacheGetDependsCount,0, + "The number of apt_pkg.Dependency objects stored in the cache."}, + {"file_list",PkgCacheGetFileList,0, + "A list of apt_pkg.PackageFile objects stored in the cache."}, + {"group_count",PkgCacheGetGroupCount,0, + "The number of apt_pkg.Group objects stored in the cache."}, + {"groups", PkgCacheGetGroups, 0, "A list of Group objects in the cache"}, + {"policy", PkgCacheGetPolicy, 0, "The PkgPolicy for the cache"}, + {"is_multi_arch", PkgCacheGetIsMultiArch, 0, + "Whether the cache supports multi-arch."}, + {"package_count",PkgCacheGetPackageCount,0, + "The number of apt_pkg.Package objects stored in the cache."}, + {"package_file_count",PkgCacheGetPackageFileCount,0, + "The number of apt_pkg.PackageFile objects stored in the cache."}, + {"packages",PkgCacheGetPackages,0, + "A list of apt_pkg.Package objects stored in the cache."}, + {"provides_count",PkgCacheGetProvidesCount,0, + "Number of Provides relations described in the cache."}, + {"ver_file_count",PkgCacheGetVerFileCount,0, + "The number of (Version, PackageFile) relations."}, + {"version_count",PkgCacheGetVersionCount,0, + "The number of apt_pkg.Version objects stored in the cache."}, + {} +}; + +// Helper to call FindPkg(name) or FindPkg(name, architecture) +static pkgCache::PkgIterator CacheFindPkg(PyObject *self, PyObject *arg) +{ + const char *name; + const char *architecture; + pkgCache *cache = GetCpp(self); + + name = PyObject_AsString(arg); + + if (name != NULL) + return cache->FindPkg(name); + + PyErr_Clear(); + + if (PyArg_ParseTuple(arg, "ss", &name, &architecture) == 0) { + PyErr_Clear(); + PyErr_Format(PyExc_TypeError, "Expected a string or a pair of strings"); + return pkgCache::PkgIterator(); + } + + return cache->FindPkg(name, architecture); +} + +// Map access, operator [] +static PyObject *CacheMapOp(PyObject *Self,PyObject *Arg) +{ + pkgCache::PkgIterator Pkg = CacheFindPkg(Self, Arg); + if (Pkg.end() == true) + { + if (!PyErr_Occurred()) + PyErr_SetObject(PyExc_KeyError,Arg); + return 0; + } + + return CppPyObject_NEW(Self,&PyPackage_Type,Pkg); +} + +// Check whether the cache contains a package with a given name. +static int CacheContains(PyObject *Self,PyObject *Arg) +{ + bool res = (CacheFindPkg(Self, Arg).end() == false); + PyErr_Clear(); + return res; +} + +static PyObject *PkgCacheNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) +{ + PyObject *pyCallbackInst = 0; + char *kwlist[] = {"progress", 0}; + + if (PyArg_ParseTupleAndKeywords(Args, kwds, "|O", kwlist, + &pyCallbackInst) == 0) + return 0; + + if (_system == 0) { + PyErr_SetString(PyExc_ValueError,"_system not initialized"); + return 0; + } + + pkgCacheFile *Cache = new pkgCacheFile(); + + if (pyCallbackInst == Py_None) { + OpProgress Prog; + if (Cache->Open(&Prog,false) == false) + return HandleErrors(); + } else if(pyCallbackInst != 0) { + // sanity check for the progress object, see #497049 + if (PyObject_HasAttrString(pyCallbackInst, "done") != true) { + PyErr_SetString(PyExc_ValueError, + "OpProgress object must implement done()"); + return 0; + } + if (PyObject_HasAttrString(pyCallbackInst, "update") != true) { + PyErr_SetString(PyExc_ValueError, + "OpProgress object must implement update()"); + return 0; + } + PyOpProgress progress; + progress.setCallbackInst(pyCallbackInst); + if (Cache->Open(&progress,false) == false) + return HandleErrors(); + } + else { + OpTextProgress Prog; + if (Cache->Open(&Prog,false) == false) + return HandleErrors(); + } + + // ensure that the states are correct (LP: #659438) + pkgApplyStatus(*Cache); + + CppPyObject *CacheFileObj = + CppPyObject_NEW(0,&PyCacheFile_Type, Cache); + + CppPyObject *CacheObj = + CppPyObject_NEW(CacheFileObj,type, + (pkgCache *)(*Cache)); + + // Do not delete the pointer to the pkgCache, it is managed by pkgCacheFile. + CacheObj->NoDelete = true; + Py_DECREF(CacheFileObj); + return CacheObj; +} + +static Py_ssize_t CacheMapLen(PyObject *Self) +{ + return GetCpp(Self)->HeaderP->PackageCount; +} + +static char *doc_PkgCache = "Cache([progress]) -> Cache() object.\n\n" + "The APT cache file contains a hash table mapping names of binary\n" + "packages to their metadata. A Cache object is the in-core\n" + "representation of the same. It provides access to APT’s idea of the\n" + "list of available packages.\n" + "The optional parameter *progress* can be used to specify an \n" + "apt.progress.base.OpProgress() object (or similar) which reports\n" + "progress information while the cache is being opened. If this\n" + "parameter is not supplied, the progress will be reported in simple,\n" + "human-readable text to standard output. If it is None, no output\n" + "will be made.\n\n" + "The cache can be used like a mapping from package names to Package\n" + "objects (although only getting items is supported). Instead of a name,\n" + "a tuple of a name and an architecture may be used."; +static PySequenceMethods CacheSeq = {0,0,0,0,0,0,0,CacheContains,0,0}; +static PyMappingMethods CacheMap = {CacheMapLen,CacheMapOp,0}; +PyTypeObject PyCache_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Cache", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &CacheSeq, // tp_as_sequence + &CacheMap, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC), + doc_PkgCache, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgCacheMethods, // tp_methods + 0, // tp_members + PkgCacheGetSet, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PkgCacheNew, // tp_new +}; + /*}}}*/ +// PkgCacheFile Class /*{{{*/ +// --------------------------------------------------------------------- +PyTypeObject PyCacheFile_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "pkgCacheFile", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags +}; + +// Package List Class /*{{{*/ +// --------------------------------------------------------------------- +static Py_ssize_t PkgListLen(PyObject *Self) +{ + return GetCpp(Self).Iter.Cache()->HeaderP->PackageCount; +} + +static PyObject *PkgListItem(PyObject *iSelf,Py_ssize_t Index) +{ + PkgListStruct &Self = GetCpp(iSelf); + + if (!Self.move(Index)) + return 0; + return CppPyObject_NEW(GetOwner(iSelf),&PyPackage_Type, + Self.Iter); +} + +static PySequenceMethods PkgListSeq = +{ + PkgListLen, + 0, // concat + 0, // repeat + PkgListItem, + 0, // slice + 0, // assign item + 0 // assign slice +}; + +static const char *packagelist_doc = + "A PackageList is an internally used structure to represent\n" + "the 'packages' attribute of apt_pkg.Cache objects in a more\n" + "efficient manner by creating Package objects only when they\n" + "are accessed."; + +PyTypeObject PyPackageList_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.PackageList", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &PkgListSeq, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags + packagelist_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear +}; + +/* The same for groups */ +static Py_ssize_t GrpListLen(PyObject *Self) +{ + return GetCpp(Self).Iter.Cache()->HeaderP->GroupCount; +} + +static PyObject *GrpListItem(PyObject *iSelf,Py_ssize_t Index) +{ + GrpListStruct &Self = GetCpp(iSelf); + + if (!Self.move(Index)) + return 0; + return CppPyObject_NEW(GetOwner(iSelf),&PyGroup_Type, + Self.Iter); +} + +static PySequenceMethods GrpListSeq = +{ + GrpListLen, + 0, // concat + 0, // repeat + GrpListItem, + 0, // slice + 0, // assign item + 0 // assign slice +}; + +static const char *grouplist_doc = + "A GroupList is an internally used structure to represent\n" + "the 'groups' attribute of apt_pkg.Cache objects in a more\n" + "efficient manner by creating Group objects only when they\n" + "are accessed."; + +PyTypeObject PyGroupList_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.GroupList", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &GrpListSeq, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags + grouplist_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear +}; + + +#define Owner (GetOwner(Self)) +#define MkGet(PyFunc,Ret) static PyObject *PyFunc(PyObject *Self,void*) \ +{ \ + pkgCache::PkgIterator &Pkg = GetCpp(Self); \ + return Ret; \ +} + +MkGet(PackageGetName,CppPyString(Pkg.Name())) +MkGet(PackageGetArch,CppPyString(Pkg.Arch())) +MkGet(PackageGetRevDependsList,CppPyObject_NEW(Owner, + &PyDependencyList_Type, Pkg.RevDependsList())) +MkGet(PackageGetProvidesList,CreateProvides(Owner,Pkg.ProvidesList())) +MkGet(PackageGetSelectedState,MkPyNumber(Pkg->SelectedState)) +MkGet(PackageGetInstState,MkPyNumber(Pkg->InstState)) +MkGet(PackageGetCurrentState,MkPyNumber(Pkg->CurrentState)) +MkGet(PackageGetID,MkPyNumber(Pkg->ID)) +# +MkGet(PackageGetEssential,PyBool_FromLong((Pkg->Flags & pkgCache::Flag::Essential) != 0)) +MkGet(PackageGetImportant,PyBool_FromLong((Pkg->Flags & pkgCache::Flag::Important) != 0)) +#undef MkGet +#undef Owner + +static const char PackageGetFullName_doc[] = + "get_fullname([pretty: bool = False]) -> str\n\n" + "Get the full name of the package, including the architecture. If\n" + "'pretty' is True, the architecture is omitted for native packages,\n" + "that is, and amd64 apt package on an amd64 system would give 'apt'."; +static PyObject *PackageGetFullName(PyObject *Self,PyObject *Args,PyObject *kwds) +{ + pkgCache::PkgIterator &Pkg = GetCpp(Self); + char pretty = 0; + char *kwlist[] = {"pretty", 0}; + + if (PyArg_ParseTupleAndKeywords(Args, kwds, "|b", kwlist, + &pretty) == 0) + return 0; + + + return CppPyString(Pkg.FullName(pretty)); +} + +static PyObject *PackageGetVersionList(PyObject *Self,void*) +{ + pkgCache::PkgIterator &Pkg = GetCpp(Self); + PyObject *Owner = GetOwner(Self); + + PyObject *List = PyList_New(0); + for (pkgCache::VerIterator I = Pkg.VersionList(); I.end() == false; I++) + { + PyObject *Obj; + Obj = CppPyObject_NEW(Owner,&PyVersion_Type,I); + PyList_Append(List,Obj); + Py_DECREF(Obj); + } + return List; +} + +static PyObject *PackageGetHasVersions(PyObject *Self,void*) +{ + pkgCache::PkgIterator &Pkg = GetCpp(Self); + return PyBool_FromLong(Pkg.VersionList().end() == false); +} + +static PyObject *PackageGetHasProvides(PyObject *Self,void*) +{ + pkgCache::PkgIterator &Pkg = GetCpp(Self); + return PyBool_FromLong(Pkg.ProvidesList().end() == false); +} + +static PyObject *PackageGetCurrentVer(PyObject *Self,void*) +{ + pkgCache::PkgIterator &Pkg = GetCpp(Self); + PyObject *Owner = GetOwner(Self); + if (Pkg->CurrentVer == 0) + { + Py_INCREF(Py_None); + return Py_None; + } + return CppPyObject_NEW(Owner,&PyVersion_Type, + Pkg.CurrentVer()); +} + + +static PyMethodDef PackageMethods[] = +{ + {"get_fullname",(PyCFunction)PackageGetFullName,METH_VARARGS|METH_KEYWORDS, + PackageGetFullName_doc}, + {} +}; + +static PyGetSetDef PackageGetSet[] = { + {"name",PackageGetName,0, + "The name of the package."}, + {"architecture",PackageGetArch,0, "The architecture of the package."}, + {"rev_depends_list",PackageGetRevDependsList,0, + "An apt_pkg.DependencyList object of all reverse dependencies."}, + {"provides_list",PackageGetProvidesList,0, + "A list of all packages providing this package. The list contains\n" + "tuples in the format (providesname, providesver, version)\n" + "where 'version' is an apt_pkg.Version object."}, + {"selected_state",PackageGetSelectedState,0, + "The state of the selection, which can be compared against the constants\n" + "SELSTATE_DEINSTALL, SELSTATE_HOLD, SELSTATE_INSTALL, SELSTATE_PURGE,\n" + "SELSTATE_UNKNOWN of the apt_pkg module."}, + {"inst_state",PackageGetInstState,0, + "The state of the install, which be compared against the constants\n" + "INSTSTATE_HOLD, INSTSTATE_HOLD_REINSTREQ, INSTSTATE_OK,\n" + "INSTSTATE_REINSTREQ of the apt_pkg module."}, + {"current_state",PackageGetCurrentState,0, + "The current state, which can be compared against the constants\n" + "CURSTATE_CONFIG_FILES, CURSTATE_HALF_CONFIGURED,\n" + "CURSTATE_HALF_INSTALLED, CURSTATE_INSTALLED, CURSTATE_NOT_INSTALLED,\n" + "CURSTATE_UNPACKED of the apt_pkg module."}, + {"id",PackageGetID,0, + "The numeric ID of the package"}, + {"essential",PackageGetEssential,0, + "Boolean value determining whether the package is essential."}, + {"important",PackageGetImportant,0, + "Boolean value determining whether the package has the 'important'\n" + "flag set ('Important: yes' in the Packages file). No longer used."}, + {"version_list",PackageGetVersionList,0, + "A list of all apt_pkg.Version objects for this package."}, + {"current_ver",PackageGetCurrentVer,0, + "The version of the package currently installed or None."}, + {"has_versions",PackageGetHasVersions,0, + "Whether the package has at least one version in the cache."}, + {"has_provides",PackageGetHasProvides,0, + "Whether the package is provided by at least one other package."}, + {} +}; + +static PyObject *PackageRepr(PyObject *Self) +{ + pkgCache::PkgIterator &Pkg = GetCpp(Self); + return PyString_FromFormat("<%s object: name:'%s' id:%u>", Self->ob_type->tp_name, + Pkg.Name(), Pkg->ID); +} + +static const char *package_doc = + "Represent a package. A package is uniquely identified by its name\n" + "and each package can have zero or more versions which can be\n" + "accessed via the version_list property. Packages can be installed\n" + "and removed by apt_pkg.DepCache."; + +PyTypeObject PyPackage_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Package", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + PackageRepr, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags + package_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear,// tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PackageMethods, // tp_methods + 0, // tp_members + PackageGetSet, // tp_getset +}; + +#define Description_MkGet(PyFunc,Ret) static PyObject \ + *PyFunc(PyObject *Self,void*) { \ + pkgCache::DescIterator &Desc = GetCpp(Self); \ + return Ret; } + +Description_MkGet(DescriptionGetLanguageCode, + CppPyString(Desc.LanguageCode())) +Description_MkGet(DescriptionGetMd5,CppPyString(Desc.md5())) +#undef Description_MkGet + +static PyObject *DescriptionGetFileList(PyObject *Self,void*) +{ + pkgCache::DescIterator &Desc = GetCpp(Self); + PyObject *Owner = GetOwner(Self); + + /* The second value in the tuple is the index of the VF item. If the + user wants to request a lookup then that number will be used. + Maybe later it can become an object. */ + PyObject *List = PyList_New(0); + for (pkgCache::DescFileIterator I = Desc.FileList(); I.end() == false; I++) + { + PyObject *DescFile; + PyObject *Obj; + DescFile = CppPyObject_NEW(Owner,&PyPackageFile_Type,I.File()); + Obj = Py_BuildValue("NN",DescFile,MkPyNumber(I.Index())); + PyList_Append(List,Obj); + Py_DECREF(Obj); + } + return List; +} + +static PyGetSetDef DescriptionGetSet[] = { + {"language_code",DescriptionGetLanguageCode,0, + "The language code of the description. Empty string for untranslated\n" + "descriptions."}, + {"md5",DescriptionGetMd5,0, + "The MD5 hash of the description."}, + {"file_list",DescriptionGetFileList,0, + "A list of all apt_pkg.PackageFile objects related to this description."}, + {} +}; + +static PyObject *DescriptionRepr(PyObject *Self) +{ + pkgCache::DescIterator &Desc = GetCpp(Self); + return PyString_FromFormat("<%s object: language_code:'%s' md5:'%s' ", + Self->ob_type->tp_name, Desc.LanguageCode(), + Desc.md5()); +} + +static const char *description_doc = + "Represent a package description and some attributes. Needed for\n" + "things like translated descriptions."; + +PyTypeObject PyDescription_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Description", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + DescriptionRepr, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags + description_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear,// tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + DescriptionGetSet, // tp_getset +}; + /*}}}*/ +// Version Class /*{{{*/ +// --------------------------------------------------------------------- + +/* This is the simple depends result, the elements are split like + ParseDepends does */ +static PyObject *MakeDepends(PyObject *Owner,pkgCache::VerIterator &Ver, + bool AsObj) +{ + PyObject *Dict = PyDict_New(); + PyObject *LastDep = 0; + unsigned LastDepType = 0; + for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false;) + { + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); + + // Switch/create a new dict entry + if (LastDepType != Start->Type || LastDep != 0) + { + PyObject *Dep = CppPyString(UntranslatedDepTypes[Start->Type]); + LastDepType = Start->Type; + LastDep = PyDict_GetItem(Dict,Dep); + if (LastDep == 0) + { + LastDep = PyList_New(0); + PyDict_SetItem(Dict,Dep,LastDep); + Py_DECREF(LastDep); + } + Py_DECREF(Dep); + } + + PyObject *OrGroup = PyList_New(0); + while (1) + { + PyObject *Obj; + if (AsObj == true) + Obj = CppPyObject_NEW(Owner,&PyDependency_Type, + Start); + else + { + if (Start->Version == 0) + Obj = Py_BuildValue("sss", + Start.TargetPkg().Name(), + "", + Start.CompType()); + else + Obj = Py_BuildValue("sss", + Start.TargetPkg().Name(), + Start.TargetVer(), + Start.CompType()); + } + PyList_Append(OrGroup,Obj); + Py_DECREF(Obj); + + if (Start == End) + break; + Start++; + } + + PyList_Append(LastDep,OrGroup); + Py_DECREF(OrGroup); + } + + return Dict; +} + +static inline pkgCache::VerIterator Version_GetVer(PyObject *Self) { + return GetCpp(Self); +} + +// Version attributes. +static PyObject *VersionGetVerStr(PyObject *Self, void*) { + return CppPyString(Version_GetVer(Self).VerStr()); +} +static PyObject *VersionGetSection(PyObject *Self, void*) { + return CppPyString(Version_GetVer(Self).Section()); +} +static PyObject *VersionGetArch(PyObject *Self, void*) { + return CppPyString(Version_GetVer(Self).Arch()); +} +static PyObject *VersionGetFileList(PyObject *Self, void*) { + pkgCache::VerIterator &Ver = GetCpp(Self); + PyObject *Owner = GetOwner(Self); + PyObject *List = PyList_New(0); + for (pkgCache::VerFileIterator I = Ver.FileList(); I.end() == false; I++) + { + PyObject *PkgFile; + PyObject *Obj; + PkgFile = CppPyObject_NEW(Owner,&PyPackageFile_Type,I.File()); + Obj = Py_BuildValue("NN",PkgFile,MkPyNumber(I.Index())); + PyList_Append(List,Obj); + Py_DECREF(Obj); + } + return List; +} + +static PyObject *VersionGetDependsListStr(PyObject *Self, void*) { + pkgCache::VerIterator &Ver = GetCpp(Self); + PyObject *Owner = GetOwner(Self); + return MakeDepends(Owner,Ver,false); +} +static PyObject *VersionGetDependsList(PyObject *Self, void*) { + pkgCache::VerIterator &Ver = GetCpp(Self); + PyObject *Owner = GetOwner(Self); + return MakeDepends(Owner,Ver,true); +} +static PyObject *VersionGetParentPkg(PyObject *Self, void*) { + PyObject *Owner = GetOwner(Self); + return CppPyObject_NEW(Owner,&PyPackage_Type, + Version_GetVer(Self).ParentPkg()); +} +static PyObject *VersionGetProvidesList(PyObject *Self, void*) { + PyObject *Owner = GetOwner(Self); + return CreateProvides(Owner,Version_GetVer(Self).ProvidesList()); +} +static PyObject *VersionGetSize(PyObject *Self, void*) { + return MkPyNumber(Version_GetVer(Self)->Size); +} +static PyObject *VersionGetInstalledSize(PyObject *Self, void*) { + return MkPyNumber(Version_GetVer(Self)->InstalledSize); +} +static PyObject *VersionGetHash(PyObject *Self, void*) { + return MkPyNumber(Version_GetVer(Self)->Hash); +} +static PyObject *VersionGetID(PyObject *Self, void*) { + return MkPyNumber(Version_GetVer(Self)->ID); +} +static PyObject *VersionGetPriority(PyObject *Self, void*) { + return MkPyNumber(Version_GetVer(Self)->Priority); +} +static PyObject *VersionGetPriorityStr(PyObject *Self, void*) { + return CppPyString(Version_GetVer(Self).PriorityType()); +} +static PyObject *VersionGetDownloadable(PyObject *Self, void*) { + return PyBool_FromLong(Version_GetVer(Self).Downloadable()); +} +static PyObject *VersionGetTranslatedDescription(PyObject *Self, void*) { + pkgCache::VerIterator &Ver = GetCpp(Self); + PyObject *Owner = GetOwner(Self); + return CppPyObject_NEW(Owner, + &PyDescription_Type, + Ver.TranslatedDescription()); +} + +static PyObject *VersionGetIsSecurityUpdate(PyObject *Self, void*) { + return PyBool_FromLong(Version_GetVer(Self).IsSecurityUpdate()); +} + +static PyObject *VersionGetMultiArch(PyObject *Self, void*) +{ + return MkPyNumber(Version_GetVer(Self)->MultiArch); +} + +#if 0 // FIXME: enable once pkgSourceList is stored somewhere +static PyObject *VersionGetIsTrusted(PyObject *Self, void*) { + else if (strcmp("IsTrusted", Name) == 0) + { + pkgSourceList Sources; + Sources.ReadMainList(); + for(pkgCache::VerFileIterator i = Ver.FileList(); !i.end(); i++) + { + pkgIndexFile *index; + if(Sources.FindIndex(i.File(), index) && !index->IsTrusted()) + Py_RETURN_FALSE; + } + Py_RETURN_TRUE; + } +} +#endif + +#define NOTNULL(x) (x ? x : "") + +static PyObject *VersionRepr(PyObject *Self) +{ + pkgCache::VerIterator &Ver = GetCpp(Self); + return PyString_FromFormat("<%s object: Pkg:'%s' Ver:'%s' Section:'%s' " + " Arch:'%s' Size:%lu ISize:%lu Hash:%u ID:%u " + "Priority:%u>", Self->ob_type->tp_name, + Ver.ParentPkg().Name(), Ver.VerStr(), + NOTNULL(Ver.Section()), NOTNULL(Ver.Arch()), + (unsigned long)Ver->Size, + (unsigned long)Ver->InstalledSize, + Ver->Hash, Ver->ID, Ver->Priority); +} +#undef NOTNULL + +static PyObject *version_richcompare(PyObject *obj1, PyObject *obj2, int op) +{ + if (!PyVersion_Check(obj2)) + return Py_INCREF(Py_NotImplemented), Py_NotImplemented; + + const pkgCache::VerIterator &a = GetCpp(obj1); + const pkgCache::VerIterator &b = GetCpp(obj2); + const int comparison = _system->VS->CmpVersion(a.VerStr(), b.VerStr()); + switch (op) { + case Py_LT: return PyBool_FromLong(comparison < 0); + case Py_LE: return PyBool_FromLong(comparison <= 0); + case Py_EQ: return PyBool_FromLong(comparison == 0); + case Py_NE: return PyBool_FromLong(comparison != 0); + case Py_GE: return PyBool_FromLong(comparison >= 0); + case Py_GT: return PyBool_FromLong(comparison > 0); + default: return NULL; // should not happen. + } +} + +static PyGetSetDef VersionGetSet[] = { + {"arch",VersionGetArch,0, + "The architecture of this specific version of the package."}, + {"depends_list",VersionGetDependsList,0, + "A dictionary mapping dependency types to lists (A) of lists (B) of\n" + "apt_pkg.Dependency objects. The lists (B) represent or dependencies\n" + "like 'a || b'."}, + {"depends_list_str",VersionGetDependsListStr,0, + "Same as depends_list, except that the apt_pkg.Dependency objects\n" + "are 3-tuples of the form (name, version, operator); where operator\n" + "is one of '<', '<=', '=', '>=', '>'."}, + {"downloadable",VersionGetDownloadable,0, + "Whether the version can be downloaded."}, + {"file_list",VersionGetFileList,0, + "A list of tuples (packagefile: apt_pkg.PackageFile, index: int) for the\n" + "PackageFile objects related to this package. The index can be used\n" + "to retrieve the record of this package version."}, + {"hash",VersionGetHash,0, + "The numeric hash of the version used in the internal storage."}, + {"id",VersionGetID,0, + "The numeric ID of the package."}, + {"installed_size",VersionGetInstalledSize,0, + "The installed size of this package version."}, + {"multi_arch",VersionGetMultiArch,0, + "Multi-arch state of this package, as an integer. See\n" + "the various MULTI_ARCH_* members."}, + {"parent_pkg",VersionGetParentPkg,0, + "The parent package of this version."}, + {"priority",VersionGetPriority,0, + "The priority of the package as an integer, which can be compared to\n" + "the constants PRI_EXTRA, PRI_IMPORTANT, PRI_OPTIONAL, PRI_REQUIRED,\n" + "PRI_STANDARD of the apt_pkg module."}, + {"priority_str",VersionGetPriorityStr,0, + "The priority of the package, as a string."}, + {"provides_list",VersionGetProvidesList,0, + "A list of all packages provided by this version. The list contains\n" + "tuples in the format (providesname, providesver, version)\n" + "where 'version' is an apt_pkg.Version object."}, + {"section",VersionGetSection,0, + "The section of this package version."}, + {"size",VersionGetSize,0, + "The size of the package file."}, + {"translated_description",VersionGetTranslatedDescription,0, + "An apt_pkg.Description object for the translated description if\n" + "available or the untranslated fallback."}, + {"is_security_update",VersionGetIsSecurityUpdate,0, + "Whether this version is a security update."}, + {"ver_str",VersionGetVerStr,0, + "The version string."}, + {} +}; + +PyTypeObject PyVersion_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Version", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + VersionRepr, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags + "Version Object", // tp_doc + CppTraverse, // tp_traverse + CppClear,// tp_clear + version_richcompare, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + VersionGetSet, // tp_getset +}; + + /*}}}*/ + +// PackageFile Class /*{{{*/ +// --------------------------------------------------------------------- +static PyObject *PackageFile_GetFileName(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return CppPyPath(File.FileName()); +} + +static PyObject *PackageFile_GetArchive(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return CppPyString(File.Archive()); +} + +static PyObject *PackageFile_GetComponent(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return CppPyString(File.Component()); +} + +static PyObject *PackageFile_GetVersion(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return CppPyString(File.Version()); +} + +static PyObject *PackageFile_GetOrigin(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return CppPyString(File.Origin()); +} + +static PyObject *PackageFile_GetLabel(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return CppPyString(File.Label()); +} + +static PyObject *PackageFile_GetArchitecture(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return CppPyString(File.Architecture()); +} + +static PyObject *PackageFile_GetCodename(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return CppPyString(File.Codename()); +} + +static PyObject *PackageFile_GetSite(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return CppPyString(File.Site()); +} + +static PyObject *PackageFile_GetIndexType(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return CppPyString(File.IndexType()); +} +static PyObject *PackageFile_GetSize(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return MkPyNumber(File->Size); +} + +static PyObject *PackageFile_GetNotSource(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return PyBool_FromLong((File->Flags & pkgCache::Flag::NotSource) != 0); +} +static PyObject *PackageFile_GetNotAutomatic(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return PyBool_FromLong((File->Flags & pkgCache::Flag::NotAutomatic) != 0); +} + +static PyObject *PackageFile_GetID(PyObject *Self,void*) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + return MkPyNumber(File->ID); +} + +#define S(s) (s == NULL ? "" : s) +static PyObject *PackageFileRepr(PyObject *Self) +{ + pkgCache::PkgFileIterator &File = GetCpp(Self); + + return PyString_FromFormat("<%s object: filename:'%s'" + " a=%s,c=%s,v=%s,o=%s,l=%s arch='%s' site='%s'" + " IndexType='%s' Size=%lu ID:%u>", + Self->ob_type->tp_name, File.FileName(), + S(File.Archive()), + S(File.Component()),S(File.Version()), + S(File.Origin()),S(File.Label()), + S(File.Architecture()),S(File.Site()), + S(File.IndexType()),File->Size,File->ID); +} +#undef S + +static PyGetSetDef PackageFileGetSet[] = { + {"architecture",PackageFile_GetArchitecture,0, + "The architecture of the package file. Unused, empty string nowadays."}, + {"archive",PackageFile_GetArchive,0, + "The archive of the package file (i.e. 'Suite' in the Release file)."}, + {"component",PackageFile_GetComponent,0, + "The component of this package file (e.g. 'main')."}, + {"codename",PackageFile_GetCodename,0, + "The codename of this package file (e.g. squeeze-updates)."}, + {"filename",PackageFile_GetFileName,0, + "The path to the file."}, + {"id",PackageFile_GetID,0, + "The numeric ID of this PackageFile object."}, + {"index_type",PackageFile_GetIndexType,0, + "A string describing the type of index. Known values are\n" + "'Debian Package Index', 'Debian Translation Index', and\n" + "'Debian dpkg status file'."}, + {"label",PackageFile_GetLabel,0, + "The label set in the release file (e.g. 'Debian')."}, + {"not_automatic",PackageFile_GetNotAutomatic,0, + "Whether the NotAutomatic flag is set in the Release file."}, + {"not_source",PackageFile_GetNotSource,0, + "Whether this package file lacks an active (sources.list) source;" + "packages listed in such a file cannot be downloaded."}, + {"origin",PackageFile_GetOrigin,0, + "The origin set in the release file."}, + {"site",PackageFile_GetSite,0, + "The hostname of the location this file comes from."}, + {"size",PackageFile_GetSize,0, + "The size of the file."}, + {"version",PackageFile_GetVersion,0, + "The version set in the release file (e.g. '5.0.X' for lenny, where X\n" + "is a point release)."}, + {} +}; + +static const char *packagefile_doc = + "A package file is an index file stored in the cache with some\n" + "additional pieces of information."; + +PyTypeObject PyPackageFile_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.PackageFile", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + PackageFileRepr, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags + packagefile_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + PackageFileGetSet, // tp_getset +}; + +// depends class +static PyObject *DependencyRepr(PyObject *Self) +{ + pkgCache::DepIterator &Dep = GetCpp(Self); + + return PyString_FromFormat("<%s object: pkg:'%s' ver:'%s' comp:'%s'>", + Self->ob_type->tp_name, Dep.TargetPkg().Name(), + (Dep.TargetVer() == 0 ? "" : Dep.TargetVer()), + Dep.CompType()); +} + +static PyObject *DepAllTargets(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + pkgCache::DepIterator &Dep = GetCpp(Self); + PyObject *Owner = GetOwner(Self); + + std::unique_ptr Vers(Dep.AllTargets()); + PyObject *List = PyList_New(0); + for (pkgCache::Version **I = Vers.get(); *I != 0; I++) + { + PyObject *Obj; + Obj = CppPyObject_NEW(Owner,&PyVersion_Type, + pkgCache::VerIterator(*Dep.Cache(),*I)); + PyList_Append(List,Obj); + Py_DECREF(Obj); + } + return List; +} + +static PyMethodDef DependencyMethods[] = +{ + {"all_targets",DepAllTargets,METH_VARARGS, + "all_targets() -> list\n\n" + "A list of all possible apt_pkg.Version objects which satisfy this\n" + "dependency."}, + {} +}; + +// Dependency Class /*{{{*/ +// --------------------------------------------------------------------- + +static PyObject *DependencyGetTargetVer(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp(Self); + if (Dep->Version == 0) + return CppPyString(""); + return CppPyString(Dep.TargetVer()); +} + +static PyObject *DependencyGetTargetPkg(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp(Self); + PyObject *Owner = GetOwner(Self); + return CppPyObject_NEW(Owner,&PyPackage_Type, + Dep.TargetPkg()); +} + +static PyObject *DependencyGetParentVer(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp(Self); + PyObject *Owner = GetOwner(Self); + return CppPyObject_NEW(Owner,&PyVersion_Type, + Dep.ParentVer()); +} + +static PyObject *DependencyGetParentPkg(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp(Self); + PyObject *Owner = GetOwner(Self); + return CppPyObject_NEW(Owner,&PyPackage_Type, + Dep.ParentPkg()); +} + +static PyObject *DependencyGetCompType(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp(Self); + return CppPyString(Dep.CompType()); +} + +static PyObject *DependencyGetCompTypeDeb(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp(Self); + return CppPyString(pkgCache::CompTypeDeb(Dep->CompareOp)); +} + +static PyObject *DependencyGetDepType(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp(Self); + return CppPyString(Dep.DepType()); +} + +static PyObject *DependencyGetDepTypeUntranslated(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp(Self); + return CppPyString(UntranslatedDepTypes[Dep->Type]); +} + +static PyObject *DependencyGetDepTypeEnum(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp(Self); + return MkPyNumber(Dep->Type); +} + +static PyObject *DependencyGetID(PyObject *Self,void*) +{ + pkgCache::DepIterator &Dep = GetCpp(Self); + return MkPyNumber(Dep->ID); +} + +static PyGetSetDef DependencyGetSet[] = { + {"comp_type",DependencyGetCompType,0, + "The type of comparison in mathematical notation, as a string, namely one " + "of:\n" + "'<', '<=', '=', '!=', '>=', '>', ''.\n" + "The empty string will be returned in case of an unversioned dependency."}, + {"comp_type_deb",DependencyGetCompTypeDeb,0, + "The type of comparison in Debian notation, as a string, namely one of:\n" + "'<<', '<=', '=', '!=', '>=', '>>', ''.\n" + "The empty string will be returned in case of an unversioned dependency.\n" + "For details see the Debian Policy Manual on the syntax of relationship " + "fields:\n" + "https://www.debian.org/doc/debian-policy/ch-relationships.html#s-depsyntax"}, + {"dep_type",DependencyGetDepType,0, + "The type of the dependency; may be translated"}, + {"dep_type_untranslated",DependencyGetDepTypeUntranslated,0, + "Same as dep_type, but guaranteed to be untranslated."}, + {"dep_type_enum",DependencyGetDepTypeEnum,0, + "Same as dep_type, but with a numeric value instead of a string. Can\n" + "be compared against the TYPE_ constants defined in this class."}, + {"id",DependencyGetID,0, + "The numeric ID of this dependency object."}, + {"parent_pkg",DependencyGetParentPkg,0, + "The apt_pkg.Package object of the package which depends."}, + {"parent_ver",DependencyGetParentVer,0, + "The apt_pkg.Version object of the package which depends."}, + {"target_pkg",DependencyGetTargetPkg,0, + "The apt_pkg.Package object of the package depended upon"}, + {"target_ver",DependencyGetTargetVer,0, + "The version of the package depended upon as a string"}, + {} +}; + +static const char *dependency_doc = + "Represent a dependency from one package version to a package,\n" + "and (optionally) a version relation (e.g. >= 1). Dependency\n" + "objects also provide useful functions like all_targets()\n" + "for selecting packages to satisfy the dependency."; + +PyTypeObject PyDependency_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Dependency", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + DependencyRepr, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags + dependency_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + DependencyMethods, // tp_methods + 0, // tp_members + DependencyGetSet, // tp_getset +}; + + /*}}}*/ + /*}}}*/ +// Reverse Dependency List Class /*{{{*/ +// --------------------------------------------------------------------- +static Py_ssize_t RDepListLen(PyObject *Self) +{ + return GetCpp(Self).Len; +} + +static PyObject *RDepListItem(PyObject *iSelf,Py_ssize_t Index) +{ + RDepListStruct &Self = GetCpp(iSelf); + if (Index < 0 || (unsigned)Index >= Self.Len) + { + PyErr_SetNone(PyExc_IndexError); + return 0; + } + + if ((unsigned)Index < Self.LastIndex) + { + Self.LastIndex = 0; + Self.Iter = Self.Start; + } + + while ((unsigned)Index > Self.LastIndex) + { + Self.LastIndex++; + Self.Iter++; + if (Self.Iter.end() == true) + { + PyErr_SetNone(PyExc_IndexError); + return 0; + } + } + + return CppPyObject_NEW(GetOwner(iSelf), + &PyDependency_Type,Self.Iter); +} + +static PySequenceMethods RDepListSeq = +{ + RDepListLen, + 0, // concat + 0, // repeat + RDepListItem, + 0, // slice + 0, // assign item + 0 // assign slice +}; + +static const char *dependencylist_doc = + "A simple list-like type for representing multiple dependency\n" + "objects in an efficient manner; without having to generate\n" + "all Dependency objects in advance."; +PyTypeObject PyDependencyList_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.DependencyList", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &RDepListSeq, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags + dependencylist_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear +}; + + /*}}}*/ + + diff --git a/python/cachegroup.cc b/python/cachegroup.cc new file mode 100644 index 0000000..4fc6c37 --- /dev/null +++ b/python/cachegroup.cc @@ -0,0 +1,188 @@ +/* + * cachegroup.cc - Wrapper around pkgCache::GrpIterator + * + * Copyright 2011 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include +#include "apt_pkgmodule.h" +#include "generic.h" +#include + +struct PyGroup : CppPyObject { + pkgCache::PkgIterator current; + int nextIndex; +}; + +static PyObject *group_new(PyTypeObject *type,PyObject *args, + PyObject *kwds) +{ + PyObject *pyCache; + char *name; + char *kwlist[] = {"cache", "name", NULL}; + if (PyArg_ParseTupleAndKeywords(args, kwds, "O!s", kwlist, + &PyCache_Type, &pyCache, + &name) == 0) + return 0; + + pkgCache *cache = GetCpp(pyCache); + + pkgCache::GrpIterator grp = cache->FindGrp(name); + + if (!grp.end()) { + return PyGroup_FromCpp(grp, true, pyCache); + } else { + PyErr_SetString(PyExc_KeyError, name); + return NULL; + } +} + +static const char group_find_package_doc[] = + "find_package(architecture: str) -> Package\n\n" + "Return a package for the given architecture, or None if none exists"; +static PyObject *group_find_package(PyObject *self,PyObject *args) +{ + pkgCache::GrpIterator grp = GetCpp(self); + PyObject *owner = GetOwner(self); + + char *architecture; + if (PyArg_ParseTuple(args, "s", &architecture) == 0) + return 0; + + pkgCache::PkgIterator pkg = grp.FindPkg(architecture); + + if (pkg.end()) { + Py_RETURN_NONE; + } else { + return PyPackage_FromCpp(pkg, true, owner ? owner : self); + } +} + +static const char group_find_preferred_package_doc[] = + "find_preferred_package(prefer_non_virtual: bool = True) -> Package\n\n" + "Return a package for the best architecture, either the native one\n" + "or the first found one. If none exists, return None. If non_virtual\n" + "is True, prefer non-virtual packages over virtual ones."; +static PyObject *group_find_preferred_package(PyObject *self,PyObject *args, + PyObject *kwds) +{ + pkgCache::GrpIterator grp = GetCpp(self); + PyObject *owner = GetOwner(self); + char nonvirtual = 1; + char *kwlist[] = {"prefer_non_virtual", NULL}; + if (PyArg_ParseTupleAndKeywords(args, kwds, "|b", kwlist, &nonvirtual) == 0) + return 0; + pkgCache::PkgIterator pkg = grp.FindPreferredPkg(nonvirtual); + + if (pkg.end()) { + Py_RETURN_NONE; + } else { + return PyPackage_FromCpp(pkg, true, owner); + } +} + +static PyMethodDef group_methods[] = { + {"find_package",group_find_package,METH_VARARGS,group_find_package_doc}, + {"find_preferred_package",(PyCFunction) group_find_preferred_package, + METH_VARARGS|METH_KEYWORDS,group_find_preferred_package_doc}, + {} +}; + +static PyObject *group_seq_item(PyObject *pySelf,Py_ssize_t index) +{ + PyGroup *self = static_cast(pySelf); + pkgCache::GrpIterator grp = GetCpp(self); + PyObject *owner = GetOwner(self); + + if (self->nextIndex > index || self->nextIndex == 0) { + self->nextIndex = 1; + new (&self->current) pkgCache::PkgIterator(grp.PackageList()); + } + + if (self->nextIndex != index + 1) { + while (self->nextIndex <= index && !self->current.end()) { + self->current = grp.NextPkg(self->current); + self->nextIndex++; + } + } + + if (self->current.end()) + return PyErr_Format(PyExc_IndexError, "Out of range: %zd", index); + + return PyPackage_FromCpp(self->current, true, owner); +} + + +static PySequenceMethods group_as_sequence = +{ + 0, + 0, // concat + 0, // repeat + group_seq_item, + 0, // slice + 0, // assign item + 0 // assign slice +}; + + +static const char group_doc[] = "Group(cache, name)\n\n" + "Group of packages with the same name.\n\n" + "Provides access to all packages sharing a name. Can be used this\n" + "like a list, or by using the special find_*() methods. If you use\n" + "it as a sequence, make sure to access it linearly, as this uses a\n" + "linked list internally."; +PyTypeObject PyGroup_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Group", // tp_name + sizeof(PyGroup), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &group_as_sequence, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + group_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + group_methods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + group_new, // tp_new +}; diff --git a/python/cdrom.cc b/python/cdrom.cc new file mode 100644 index 0000000..392dd83 --- /dev/null +++ b/python/cdrom.cc @@ -0,0 +1,139 @@ +/* cdrom.cc - Wrapper for pkgCdrom. + * + * Copyright 2004-2009 Canonical Ltd. + * Copyright 2009 Julian Andres Klode + * + * Authors: Michael Vogt + * Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "generic.h" +#include "apt_pkgmodule.h" +#include "progress.h" + +#include + +static char *cdrom_add_doc = + "add(progress: apt_pkg.CdromProgress) -> bool\n\n" + "Add the given CD-ROM to the sources.list. Return True on success;\n" + "raise an error on failure or return False."; +static PyObject *cdrom_add(PyObject *Self,PyObject *Args) +{ + pkgCdrom &Cdrom = GetCpp(Self); + + PyObject *pyCdromProgressInst = 0; + if (PyArg_ParseTuple(Args, "O", &pyCdromProgressInst) == 0) { + return 0; + } + + PyCdromProgress progress; + progress.setCallbackInst(pyCdromProgressInst); + + bool res = Cdrom.Add(&progress); + + return HandleErrors(PyBool_FromLong(res)); +} + +static char *cdrom_ident_doc = + "ident(progress: apt_pkg.CdromProgress) -> str\n\n" + "Try to identify the CD-ROM and if successful return the hexadecimal\n" + "CDROM-ID (and a integer version suffix separated by -) as a\n" + "string. Otherwise, return None or raise an error.\n\n" + "The ID is created by hashing all file and directory names on the\n" + "CD-ROM and appending the version."; +static PyObject *cdrom_ident(PyObject *Self,PyObject *Args) +{ + pkgCdrom &Cdrom = GetCpp(Self); + PyObject *pyCdromProgressInst = 0; + if (PyArg_ParseTuple(Args, "O", &pyCdromProgressInst) == 0) { + return 0; + } + + PyCdromProgress progress; + progress.setCallbackInst(pyCdromProgressInst); + + std::string ident; + bool res = Cdrom.Ident(ident, &progress); + + if (res) + return CppPyString(ident); + else { + Py_INCREF(Py_None); + return HandleErrors(Py_None); + } +} + + +static PyMethodDef cdrom_methods[] = { + {"add",cdrom_add,METH_VARARGS,cdrom_add_doc}, + {"ident",cdrom_ident,METH_VARARGS,cdrom_ident_doc}, + {} +}; + +static PyObject *cdrom_new(PyTypeObject *type,PyObject *Args,PyObject *kwds) +{ + return CppPyObject_NEW(NULL, type); +} + +static char *cdrom_doc = + "Cdrom()\n\n" + "Cdrom objects can be used to identify Debian installation media and to\n" + "add them to /etc/apt/sources.list."; +PyTypeObject PyCdrom_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Cdrom", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE, + cdrom_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + cdrom_methods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + cdrom_new, // tp_new +}; + diff --git a/python/configuration.cc b/python/configuration.cc new file mode 100644 index 0000000..dab2cc4 --- /dev/null +++ b/python/configuration.cc @@ -0,0 +1,613 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: configuration.cc,v 1.4 2003/06/03 03:22:27 mdz Exp $ +/* ###################################################################### + + Configuration - Binding for the configuration object. + + The Configuration object can have an owner (a parent Configuration object), + and it always uses a pointer. + + The wrapping is mostly 1:1 with the C++ code, but there are additions to + wrap the linked tree walking into nice flat sequence walking. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "generic.h" +#include "apt_pkgmodule.h" + +#include +#include +#include +#include + /*}}}*/ + +// GetSelf - Convert PyObject to Configuration /*{{{*/ +// --------------------------------------------------------------------- +/* */ +static inline Configuration &GetSelf(PyObject *Obj) +{ + return *GetCpp(Obj); +} + /*}}}*/ + +// Method Wrappers /*{{{*/ +static const char *doc_Find = + "find(key: str[, default: str = '']) -> str\n\n" + "Find the value for the given key and return it. If the\n" + "given key does not exist, return default instead."; +static PyObject *CnfFind(PyObject *Self,PyObject *Args) +{ + char *Name = 0; + char *Default = 0; + if (PyArg_ParseTuple(Args,"s|s",&Name,&Default) == 0) + return 0; + return CppPyString(GetSelf(Self).Find(Name,Default)); +} + +static const char *doc_FindFile = + "find_file(key: str[, default: str = '']) -> str\n\n" + "Same as find(), but for filenames. In the APT configuration, there\n" + "is a special section Dir:: for storing filenames. find_file() locates\n" + "the given key and then goes up and prepends the directory names to the\n" + "return value. For example, for:\n" + "\n" + " apt_pkg.config['Dir'] = 'a'\n" + " apt_pkg.config['Dir::D'] = 'b'\n" + " apt_pkg.config['Dir::D::F'] = 'c'\n" + "\n" + "find_file('Dir::D::F') returns 'a/b/c'. There is also a special\n" + "configuration setting RootDir which will always be prepended to the\n" + "result (the default being ''). Thus, if RootDir is 'x', the example\n" + "would return 'x/a/b/c'."; +static PyObject *CnfFindFile(PyObject *Self,PyObject *Args) +{ + char *Name = 0; + char *Default = 0; + if (PyArg_ParseTuple(Args,"s|s",&Name,&Default) == 0) + return 0; + return CppPyPath(GetSelf(Self).FindFile(Name,Default)); +} + +static const char *doc_FindDir = + "find_dir(key: str[, default: str = '']) -> str\n\n" + "Same as find_file(), but for directories. The difference is\n" + "that this function adds a trailing slash to the result."; +static PyObject *CnfFindDir(PyObject *Self,PyObject *Args) +{ + char *Name = 0; + char *Default = 0; + if (PyArg_ParseTuple(Args,"s|s",&Name,&Default) == 0) + return 0; + return CppPyPath(GetSelf(Self).FindDir(Name,Default)); +} + +static const char *doc_FindI = + "find_i(key: str[, default: int = 0]) -> int\n\n" + "Same as find, but for integer values."; +static PyObject *CnfFindI(PyObject *Self,PyObject *Args) +{ + char *Name = 0; + int Default = 0; + if (PyArg_ParseTuple(Args,"s|i",&Name,&Default) == 0) + return 0; + return MkPyNumber(GetSelf(Self).FindI(Name,Default)); +} + +static const char *doc_FindB = + "find_i(key: str[, default: bool = False]) -> bool\n\n" + "Same as find, but for boolean values; returns False on unknown values."; +static PyObject *CnfFindB(PyObject *Self,PyObject *Args) +{ + char *Name = 0; + int Default = 0; + if (PyArg_ParseTuple(Args,"s|i",&Name,&Default) == 0) + return 0; + return PyBool_FromLong(GetSelf(Self).FindB(Name,(Default == 0?false:true))); +} + +static const char *doc_Set = + "set(key: str, value: str)\n\n" + "Set the given key to the given value. To set int or bool values,\n" + "encode them using str(value) and then use find_i()/find_b()\n" + "to retrieve their value again."; +static PyObject *CnfSet(PyObject *Self,PyObject *Args) +{ + char *Name = 0; + char *Value = 0; + if (PyArg_ParseTuple(Args,"ss",&Name,&Value) == 0) + return 0; + + GetSelf(Self).Set(Name,Value); + Py_INCREF(Py_None); + return Py_None; +} + +static const char *doc_Exists = + "exists(key: str) -> bool\n\n" + "Check whether the given key exists."; +static PyObject *CnfExists(PyObject *Self,PyObject *Args) +{ + char *Name = 0; + if (PyArg_ParseTuple(Args,"s",&Name) == 0) + return 0; + return PyBool_FromLong((int)GetSelf(Self).Exists(Name)); +} + +static int CnfContains(PyObject *Self,PyObject *Arg) +{ + return (int)GetSelf(Self).Exists(PyString_AsString(Arg)); +} + +static const char *doc_Clear = + "clear(key: str)\n\n" + "Remove the specified option and all sub-options."; +static PyObject *CnfClear(PyObject *Self,PyObject *Args) +{ + char *Name = 0; + if (PyArg_ParseTuple(Args,"s",&Name) == 0) + return 0; + + GetSelf(Self).Clear(Name); + + Py_INCREF(Py_None); + return Py_None; +} + +// The amazing narrowing search ability! +static const char *doc_SubTree = + "subtree(key: str) -> apt_pkg.Configuration\n\n" + + "Return a new apt_pkg.Configuration object with the given option\n" + "as its root. Example:\n\n" + " apttree = config.subtree('APT')\n" + " apttree['Install-Suggests'] = config['APT::Install-Suggests']"; +static PyObject *CnfSubTree(PyObject *Self,PyObject *Args) +{ + char *Name; + if (PyArg_ParseTuple(Args,"s",&Name) == 0) + return 0; + const Configuration::Item *Itm = GetSelf(Self).Tree(Name); + if (Itm == 0) + { + PyErr_SetString(PyExc_KeyError,Name); + return 0; + } + + return CppPyObject_NEW(Self,&PyConfiguration_Type, + new Configuration(Itm)); +} + +// Return a list of items at a specific level +static char *doc_List = + "list([root: str]) -> list\n\n" + "Return a list of all items at the given root, using their full\n" + "name. For example, in a configuration object where the options A,\n" + "B, and B::C are set, the following expressions evaluate to True:\n\n" + " conf.list() == ['A', 'B']\n" + " conf.list('A') == ['']\n" + " conf.list('B') == ['B::C']\n"; +static PyObject *CnfList(PyObject *Self,PyObject *Args) +{ + char *RootName = 0; + if (PyArg_ParseTuple(Args,"|s",&RootName) == 0) + return 0; + + // Convert the whole configuration space into a list + PyObject *List = PyList_New(0); + const Configuration::Item *Top = GetSelf(Self).Tree(RootName); + if (!GetSelf(Self).Tree(0)) + return List; + const Configuration::Item *Root = GetSelf(Self).Tree(0)->Parent; + if (Top != 0 && RootName != 0) + Top = Top->Child; + for (; Top != 0; Top = Top->Next) + { + PyObject *Obj; + PyList_Append(List,Obj = CppPyString(Top->FullTag(Root))); + Py_DECREF(Obj); + } + + return List; +} + +/* Return a list of values of items at a specific level.. This is used to + get out value lists */ +static char *doc_ValueList = + "value_list([root: str]) -> list\n\n" + "Same as list(), but instead of returning the keys, return the values."; +static PyObject *CnfValueList(PyObject *Self,PyObject *Args) +{ + char *RootName = 0; + if (PyArg_ParseTuple(Args,"|s",&RootName) == 0) + return 0; + + // Convert the whole configuration space into a list + PyObject *List = PyList_New(0); + const Configuration::Item *Top = GetSelf(Self).Tree(RootName); + if (Top != 0 && RootName != 0) + Top = Top->Child; + for (; Top != 0; Top = Top->Next) + { + PyObject *Obj; + PyList_Append(List,Obj = CppPyString(Top->Value)); + Py_DECREF(Obj); + } + + return List; +} + +static char *doc_MyTag = + "my_tag() -> str\n\n" + "Return the tag of the root of this Configuration object. For the\n" + "default object, this is an empty string. For a subtree('APT') of\n" + "such an object, it would be 'APT' (given as an example)."; +static PyObject *CnfMyTag(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + const Configuration::Item *Top = GetSelf(Self).Tree(0); + if (Top == 0) + return Py_BuildValue("s",""); + return CppPyString(Top->Parent->Tag); +} + +static char *doc_Dump = + "dump() -> str\n\n" + "Return a string dump this Configuration object."; +static PyObject *CnfDump(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + std::stringstream ss; + GetSelf(Self).Dump(ss); + return CppPyString(ss.str()); +} + + +// Look like a mapping +static char *doc_Keys = + "keys([root: str]) -> list\n\n" + "Return a list of all keys in the configuration object. If 'root'\n" + "is given, limit the list to those below the root."; +static PyObject *CnfKeys(PyObject *Self,PyObject *Args) +{ + char *RootName = 0; + if (PyArg_ParseTuple(Args,"|s",&RootName) == 0) + return 0; + + // Convert the whole configuration space into a list + PyObject *List = PyList_New(0); + const Configuration::Item *Top = GetSelf(Self).Tree(RootName); + const Configuration::Item *Stop = Top; + const Configuration::Item *Root = 0; + if (RootName == 0) + Stop = 0; + if (Top != 0 && GetSelf(Self).Tree(0)) + Root = GetSelf(Self).Tree(0)->Parent; + for (; Top != 0;) + { + PyObject *Obj; + PyList_Append(List,Obj = CppPyString(Top->FullTag(Root))); + Py_DECREF(Obj); + + if (Top->Child != 0) + { + Top = Top->Child; + continue; + } + + while (Top != 0 && Top->Next == 0 && Top != Root && + Top->Parent != Stop) + Top = Top->Parent; + if (Top != 0) + Top = Top->Next; + } + + return List; +} + +// Map access, operator [] +static PyObject *CnfMap(PyObject *Self,PyObject *Arg) +{ + if (PyString_Check(Arg) == 0) + { + PyErr_SetNone(PyExc_TypeError); + return 0; + } + + if (GetSelf(Self).Exists(PyString_AsString(Arg)) == false) + { + PyErr_SetString(PyExc_KeyError,PyString_AsString(Arg)); + return 0; + } + + return CppPyString(GetSelf(Self).Find(PyString_AsString(Arg))); +} + +// Assignment with operator [] +static int CnfMapSet(PyObject *Self,PyObject *Arg,PyObject *Val) +{ + if (PyString_Check(Arg) == 0 || (Val != NULL && PyString_Check(Val) == 0)) + { + PyErr_SetNone(PyExc_TypeError); + return -1; + } + + if (Val == NULL) + GetSelf(Self).Clear(PyString_AsString(Arg)); + else + GetSelf(Self).Set(PyString_AsString(Arg),PyString_AsString(Val)); + return 0; +} + /*}}}*/ +// Config file loaders /*{{{*/ +char *doc_LoadConfig = + "read_config_file(configuration: apt_pkg.Configuration, filename: str)\n\n" + "Read the configuration file 'filename' and set the appropriate\n" + "options in the configuration object."; +PyObject *LoadConfig(PyObject *Self,PyObject *Args) +{ + PyApt_Filename Name; + if (PyArg_ParseTuple(Args,"OO&",&Self,PyApt_Filename::Converter, &Name) == 0) + return 0; + if (PyConfiguration_Check(Self)== 0) + { + PyErr_SetString(PyExc_TypeError,"argument 1: expected Configuration."); + return 0; + } + + if (ReadConfigFile(GetSelf(Self),Name,false) == false) + return HandleErrors(); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} +char *doc_LoadConfigISC = + "read_config_file_isc(configuration: apt_pkg.Configuration, filename: str)\n\n" + "Like read_config_file(), but for configuration files like bind's\n" + "named.conf. They have a slightly different format than APT\n" + "configuration files."; +PyObject *LoadConfigISC(PyObject *Self,PyObject *Args) +{ + PyApt_Filename Name; + if (PyArg_ParseTuple(Args,"OO&",&Self,PyApt_Filename::Converter, &Name) == 0) + return 0; + if (PyConfiguration_Check(Self)== 0) + { + PyErr_SetString(PyExc_TypeError,"argument 1: expected Configuration."); + return 0; + } + + if (ReadConfigFile(GetSelf(Self),Name,true) == false) + return HandleErrors(); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} +char *doc_LoadConfigDir = + "read_config_dir(configuration: apt_pkg.Configuration, dirname: str)\n\n" + "Read all configuration files in the dir given by 'dirname' in the\n" + "correct order."; +PyObject *LoadConfigDir(PyObject *Self,PyObject *Args) +{ + PyApt_Filename Name; + if (PyArg_ParseTuple(Args,"OO&",&Self,PyApt_Filename::Converter, &Name) == 0) + return 0; + if (PyConfiguration_Check(Self)== 0) + { + PyErr_SetString(PyExc_TypeError,"argument 1: expected Configuration."); + return 0; + } + + if (ReadConfigDir(GetSelf(Self),Name,false) == false) + return HandleErrors(); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + /*}}}*/ + +// ParseCommandLine - Wrapper for the command line interface /*{{{*/ +// --------------------------------------------------------------------- +char *doc_ParseCommandLine = +"parse_commandLine(config: Configuration, options: list, argv: list) -> list\n" +"\n" +"Parse the command line in 'argv' into the configuration space. The\n" +"list 'options' contains a list of 3-tuples or 4-tuples in the form:\n" +"\n" +" (short_option: str, long_option: str, variable: str[, type: str])\n" +"\n" +"The element 'short_option' is one character, the 'long_option' element\n" +"is the name of the long option, the element 'variable' the name of the\n" +"configuration option the result will be stored in and type is one of\n" +"'HasArg', 'IntLevel', 'Boolean', 'InvBoolean', 'ConfigFile',\n" +"'ArbItem'. The default type is 'Boolean'. Read the online documentation\n" +"in python-apt-doc and its tutorial on writing an apt-cdrom clone for more\n" +"details."; +PyObject *ParseCommandLine(PyObject *Self,PyObject *Args) +{ + PyObject *POList; + PyObject *Pargv; + if (PyArg_ParseTuple(Args,"OO!O!",&Self, + &PyList_Type,&POList,&PyList_Type,&Pargv) == 0) + return 0; + if (PyConfiguration_Check(Self)== 0) + { + PyErr_SetString(PyExc_TypeError,"argument 1: expected Configuration."); + return 0; + } + + if (PySequence_Length(Pargv) < 1) { + PyErr_SetString(PyExc_ValueError,"argv is an empty sequence"); + return 0; + } + // Convert the option list + int Length = PySequence_Length(POList); + CommandLine::Args *OList = new CommandLine::Args[Length+1]; + OList[Length].ShortOpt = 0; + OList[Length].LongOpt = 0; + + for (int I = 0; I != Length; I++) + { + char *Type = 0; + #if PY_MAJOR_VERSION >= 3 + if (PyArg_ParseTuple(PySequence_GetItem(POList,I),"Czs|s", + #else + if (PyArg_ParseTuple(PySequence_GetItem(POList,I),"czs|s", + #endif + &OList[I].ShortOpt,&OList[I].LongOpt, + &OList[I].ConfName,&Type) == 0) + { + delete [] OList; + return 0; + } + OList[I].Flags = 0; + + // Convert the type over to flags.. + if (Type != 0) + { + if (strcasecmp(Type,"HasArg") == 0) + OList[I].Flags = CommandLine::HasArg; + else if (strcasecmp(Type,"IntLevel") == 0) + OList[I].Flags = CommandLine::IntLevel; + else if (strcasecmp(Type,"Boolean") == 0) + OList[I].Flags = CommandLine::Boolean; + else if (strcasecmp(Type,"InvBoolean") == 0) + OList[I].Flags = CommandLine::InvBoolean; + else if (strcasecmp(Type,"ConfigFile") == 0) + OList[I].Flags = CommandLine::ConfigFile; + else if (strcasecmp(Type,"ArbItem") == 0) + OList[I].Flags = CommandLine::ArbItem; + } + } + + // Convert the argument list into a char ** + const char **argv = ListToCharChar(Pargv); + if (argv == 0) + { + delete [] OList; + return 0; + } + + // Do the command line processing + PyObject *List = 0; + { + CommandLine CmdL(OList,&GetSelf(Self)); + if (CmdL.Parse(PySequence_Length(Pargv),argv) == false) + { + delete [] argv; + delete [] OList; + return HandleErrors(); + } + + // Convert the file listing into a python sequence + for (Length = 0; CmdL.FileList[Length] != 0; Length++); + List = PyList_New(Length); + for (int I = 0; CmdL.FileList[I] != 0; I++) + { + PyList_SetItem(List,I,CppPyString(CmdL.FileList[I])); + } + } + + delete [] argv; + delete [] OList; + return HandleErrors(List); +} + /*}}}*/ + +// Method table for the Configuration object +static PyMethodDef CnfMethods[] = +{ + // Query + {"find",CnfFind,METH_VARARGS,doc_Find}, + {"find_file",CnfFindFile,METH_VARARGS,doc_FindFile}, + {"find_dir",CnfFindDir,METH_VARARGS,doc_FindDir}, + {"find_i",CnfFindI,METH_VARARGS,doc_FindI}, + {"find_b",CnfFindB,METH_VARARGS,doc_FindB}, + + // Others + {"set",CnfSet,METH_VARARGS,doc_Set}, + {"exists",CnfExists,METH_VARARGS,doc_Exists}, + {"subtree",CnfSubTree,METH_VARARGS,doc_SubTree}, + {"list",CnfList,METH_VARARGS,doc_List}, + {"value_list",CnfValueList,METH_VARARGS,doc_ValueList}, + {"my_tag",CnfMyTag,METH_VARARGS,doc_MyTag}, + {"clear",CnfClear,METH_VARARGS,doc_Clear}, + {"dump",CnfDump,METH_VARARGS,doc_Dump}, + // Python Special + {"keys",CnfKeys,METH_VARARGS,doc_Keys}, + #if PY_MAJOR_VERSION < 3 + {"has_key",CnfExists,METH_VARARGS,doc_Exists}, + #endif + {"get",CnfFind,METH_VARARGS,doc_Find}, + {} +}; + +static PyObject *CnfNew(PyTypeObject *type, PyObject *args, PyObject *kwds) { + char *kwlist[] = {NULL}; + if (PyArg_ParseTupleAndKeywords(args,kwds,"",kwlist) == 0) + return 0; + return CppPyObject_NEW(NULL, type, new Configuration()); +} + +// Type for a Normal Configuration object +static PySequenceMethods ConfigurationSeq = {0,0,0,0,0,0,0,CnfContains,0,0}; +static PyMappingMethods ConfigurationMap = {0,CnfMap,CnfMapSet}; + +static const char *configuration_doc = + "Configuration()\n\n" + "Represent the configuration of APT by mapping option keys to\n" + "values and storing configuration parsed from files like\n" + "/etc/apt/apt.conf. The most important Configuration object\n" + "is apt_pkg.config which points to the global configuration\n" + "object. Other top-level Configuration objects can be created\n" + "by calling the constructor, but there is usually no reason to."; + +PyTypeObject PyConfiguration_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Configuration", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &ConfigurationSeq, // tp_as_sequence + &ConfigurationMap, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE), + configuration_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + CnfMethods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + CnfNew, // tp_new +}; + diff --git a/python/depcache.cc b/python/depcache.cc new file mode 100644 index 0000000..ed766c4 --- /dev/null +++ b/python/depcache.cc @@ -0,0 +1,1169 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: depcache.cc,v 1.5 2003/06/03 03:03:23 mdz Exp $ +/* ###################################################################### + + DepCache - Wrapper for the depcache related functions + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "generic.h" +#include "apt_pkgmodule.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "progress.h" + +#ifndef _ +#define _(x) (x) +#endif + + +#define VALIDATE_ITERATOR(I) do { \ + if ((I).Cache() != &depcache->GetCache()) { \ + PyErr_SetString(PyAptCacheMismatchError, "Object of different cache passed as argument to apt_pkg.DepCache method"); \ + return nullptr; \ + } \ +} while(0) + + +// DepCache Class /*{{{*/ +// --------------------------------------------------------------------- + + + +static PyObject *PkgDepCacheInit(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *pyCallbackInst = 0; + if (PyArg_ParseTuple(Args, "|O", &pyCallbackInst) == 0) + return 0; + + if(pyCallbackInst != 0) { + PyOpProgress progress; + progress.setCallbackInst(pyCallbackInst); + depcache->Init(&progress); + } else { + depcache->Init(0); + } + + pkgApplyStatus(*depcache); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyObject *PkgDepCacheCommit(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *pyInstallProgressInst = 0; + PyObject *pyFetchProgressInst = 0; + if (PyArg_ParseTuple(Args, "OO", + &pyFetchProgressInst, &pyInstallProgressInst) == 0) { + return 0; + } + + pkgAcquire Fetcher; + if (Fetcher.GetLock(_config->FindDir("Dir::Cache::Archives")) == false) { + Py_INCREF(Py_None); + return HandleErrors(Py_None); + } + + pkgRecords Recs(*depcache); + if (_error->PendingError() == true) + HandleErrors(Py_None); + + pkgSourceList List; + if(!List.ReadMainList()) + return HandleErrors(Py_None); + + PyFetchProgress progress; + progress.setCallbackInst(pyFetchProgressInst); + + pkgPackageManager *PM; + PM = _system->CreatePM(depcache); + + Fetcher.SetLog(&progress); + + if(PM->GetArchives(&Fetcher, &List, &Recs) == false || + _error->PendingError() == true) { + std::cerr << "Error in GetArchives" << std::endl; + return HandleErrors(); + } + + PyInstallProgress iprogress; + iprogress.setCallbackInst(pyInstallProgressInst); + + // Run it + while (1) + { + bool Transient = false; + + if (Fetcher.Run() == pkgAcquire::Failed) + return HandleErrors(); + + // Print out errors + bool Failed = false; + for (pkgAcquire::ItemIterator I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++) + { + + if ((*I)->Status == pkgAcquire::Item::StatDone && + (*I)->Complete == true) + continue; + + if ((*I)->Status == pkgAcquire::Item::StatIdle) + { + Transient = true; + //Failed = true; + continue; + } + + _error->Warning(_("Failed to fetch %s %s\n"),(*I)->DescURI().c_str(), + (*I)->ErrorText.c_str()); + Failed = true; + } + + if (Transient == true && Failed == true) + { + _error->Error(_("--fix-missing and media swapping is not currently supported")); + Py_INCREF(Py_None); + return HandleErrors(Py_None); + } + + // Try to deal with missing package files + if (Failed == true && PM->FixMissing() == false) + { + _error->Error("Aborting install."); + Py_INCREF(Py_None); + return HandleErrors(Py_None); + } + + // fail if something else went wrong + //FIXME: make this more flexible, e.g. with a failedDl handler + if(Failed) + Py_RETURN_FALSE; + _system->UnLockInner(true); + + pkgPackageManager::OrderResult Res = iprogress.Run(PM); + + if (Res == pkgPackageManager::Failed || _error->PendingError() == true) { + return HandleErrors(PyBool_FromLong(false)); + } + if (Res == pkgPackageManager::Completed) { + Py_RETURN_TRUE; + } + + // Reload the fetcher object and loop again for media swapping + Fetcher.Shutdown(); + if (PM->GetArchives(&Fetcher,&List,&Recs) == false) { + Py_RETURN_FALSE; + } + _system->LockInner(); + } + + return HandleErrors(Py_None); +} + +static PyObject *PkgDepCacheSetCandidateRelease(PyObject *Self,PyObject *Args) +{ + bool Success; + PyObject *PackageObj; + PyObject *VersionObj; + const char *target_rel; + std::list > Changed; + if (PyArg_ParseTuple(Args,"O!O!s", + &PyPackage_Type, &PackageObj, + &PyVersion_Type, &VersionObj, + &target_rel) == 0) + return 0; + + pkgDepCache *depcache = GetCpp(Self); + pkgCache::VerIterator &I = GetCpp(VersionObj); + if(I.end()) { + return HandleErrors(PyBool_FromLong(false)); + } + VALIDATE_ITERATOR(I); + + Success = depcache->SetCandidateRelease(I, target_rel, Changed); + + return HandleErrors(PyBool_FromLong(Success)); +} + +static PyObject *PkgDepCacheSetCandidateVer(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + PyObject *PackageObj; + PyObject *VersionObj; + if (PyArg_ParseTuple(Args,"O!O!", + &PyPackage_Type, &PackageObj, + &PyVersion_Type, &VersionObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + + VALIDATE_ITERATOR(Pkg); + + pkgCache::VerIterator &I = GetCpp(VersionObj); + if(I.end()) { + return HandleErrors(PyBool_FromLong(false)); + } + VALIDATE_ITERATOR(I); + + if (I.ParentPkg() != Pkg) { + PyErr_SetString(PyExc_ValueError, "Version does not belong to package"); + return nullptr; + } + + depcache->SetCandidateVersion(I); + + return HandleErrors(PyBool_FromLong(true)); +} + +static PyObject *PkgDepCacheGetCandidateVer(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + PyObject *PackageObj; + PyObject *CandidateObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + + VALIDATE_ITERATOR(Pkg); + + pkgDepCache::StateCache & State = (*depcache)[Pkg]; + pkgCache::VerIterator I = State.CandidateVerIter(*depcache); + + if(I.end()) { + Py_INCREF(Py_None); + return Py_None; + } + CandidateObj = CppPyObject_NEW(PackageObj,&PyVersion_Type,I); + + return CandidateObj; +} + +static PyObject *PkgDepCacheUpgrade(PyObject *Self,PyObject *Args) +{ + bool res; + pkgDepCache *depcache = GetCpp(Self); + + char distUpgrade=0; + if (PyArg_ParseTuple(Args,"|b",&distUpgrade) == 0) + return 0; + + Py_BEGIN_ALLOW_THREADS + if(distUpgrade) + res = APT::Upgrade::Upgrade(*depcache, 0); + else + res = APT::Upgrade::Upgrade(*depcache, APT::Upgrade::FORBID_REMOVE_PACKAGES | + APT::Upgrade::FORBID_INSTALL_NEW_PACKAGES); + Py_END_ALLOW_THREADS + + Py_INCREF(Py_None); + return HandleErrors(PyBool_FromLong(res)); +} + +static PyObject *PkgDepCacheMinimizeUpgrade(PyObject *Self,PyObject *Args) +{ + bool res; + pkgDepCache *depcache = GetCpp(Self); + + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + Py_BEGIN_ALLOW_THREADS + res = pkgMinimizeUpgrade(*depcache); + Py_END_ALLOW_THREADS + + Py_INCREF(Py_None); + return HandleErrors(PyBool_FromLong(res)); +} + + +static PyObject *PkgDepCacheReadPinFile(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + + char *file=NULL; + if (PyArg_ParseTuple(Args,"|s",&file) == 0) + return 0; + + if(file == NULL) + ReadPinFile((pkgPolicy&)depcache->GetPolicy()); + else + ReadPinFile((pkgPolicy&)depcache->GetPolicy(), file); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + + +static PyObject *PkgDepCacheFixBroken(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + bool res=true; + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + res &=pkgFixBroken(*depcache); + res &=pkgMinimizeUpgrade(*depcache); + + return HandleErrors(PyBool_FromLong(res)); +} + + +static PyObject *PkgDepCacheMarkKeep(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + depcache->MarkKeep(Pkg); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyObject *PkgDepCacheSetReInstall(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + char value = 0; + if (PyArg_ParseTuple(Args,"O!b",&PyPackage_Type,&PackageObj, &value) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + depcache->SetReInstall(Pkg,value); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + + +static PyObject *PkgDepCacheMarkDelete(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + char purge = 0; + if (PyArg_ParseTuple(Args,"O!|b",&PyPackage_Type,&PackageObj, &purge) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + depcache->MarkDelete(Pkg,purge); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + + +static PyObject *PkgDepCacheMarkInstall(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + char autoInst=1; + char fromUser=1; + if (PyArg_ParseTuple(Args,"O!|bb",&PyPackage_Type,&PackageObj, + &autoInst, &fromUser) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + + Py_BEGIN_ALLOW_THREADS + depcache->MarkInstall(Pkg, autoInst, 0, fromUser); + Py_END_ALLOW_THREADS + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyObject *PkgDepCacheMarkAuto(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + char value = 0; + if (PyArg_ParseTuple(Args,"O!b",&PyPackage_Type,&PackageObj, &value) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + depcache->MarkAuto(Pkg,value); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyObject *PkgDepCacheIsUpgradable(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + pkgDepCache::StateCache &state = (*depcache)[Pkg]; + + return HandleErrors(PyBool_FromLong(state.Upgradable())); +} + +static PyObject *PkgDepCacheIsGarbage(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + pkgDepCache::StateCache &state = (*depcache)[Pkg]; + + return HandleErrors(PyBool_FromLong(state.Garbage)); +} + +static PyObject *PkgDepCacheIsAutoInstalled(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + pkgDepCache::StateCache &state = (*depcache)[Pkg]; + + return HandleErrors(PyBool_FromLong(state.Flags & pkgCache::Flag::Auto)); +} + +static PyObject *PkgDepCacheIsNowBroken(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + pkgDepCache::StateCache &state = (*depcache)[Pkg]; + + return HandleErrors(PyBool_FromLong(state.NowBroken())); +} + +static PyObject *PkgDepCacheIsInstBroken(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + pkgDepCache::StateCache &state = (*depcache)[Pkg]; + + return HandleErrors(PyBool_FromLong(state.InstBroken())); +} + + +static PyObject *PkgDepCacheMarkedInstall(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + pkgDepCache::StateCache &state = (*depcache)[Pkg]; + + return HandleErrors(PyBool_FromLong(state.NewInstall())); +} + + +static PyObject *PkgDepCacheMarkedUpgrade(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + pkgDepCache::StateCache &state = (*depcache)[Pkg]; + + return HandleErrors(PyBool_FromLong(state.Upgrade())); +} + +static PyObject *PkgDepCacheMarkedDelete(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + pkgDepCache::StateCache &state = (*depcache)[Pkg]; + + return HandleErrors(PyBool_FromLong(state.Delete())); +} + +static PyObject *PkgDepCacheMarkedKeep(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + pkgDepCache::StateCache &state = (*depcache)[Pkg]; + + return HandleErrors(PyBool_FromLong(state.Keep())); +} + +static PyObject *PkgDepCacheMarkedDowngrade(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + pkgDepCache::StateCache &state = (*depcache)[Pkg]; + + return HandleErrors(PyBool_FromLong(state.Downgrade())); +} + +static PyObject *PkgDepCacheMarkedReinstall(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + pkgDepCache::StateCache &state = (*depcache)[Pkg]; + + bool res = state.Install() && (state.iFlags & pkgDepCache::ReInstall); + + return HandleErrors(PyBool_FromLong(res)); +} + +static PyObject *PkgDepCachePhasingApplied(PyObject *Self,PyObject *Args) +{ + pkgDepCache *depcache = GetCpp(Self); + + bool res=false; + PyObject *PackageObj; + + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + + pkgCache::PkgIterator Pkg = GetCpp(PackageObj); + res = depcache->PhasingApplied(Pkg); + + return HandleErrors(PyBool_FromLong(res)); +} + +static PyMethodDef PkgDepCacheMethods[] = +{ + {"init",PkgDepCacheInit,METH_VARARGS, + "init(progress: apt.progress.base.OpProgress)\n\n" + "Initialize the depcache (done automatically when constructing\n" + "the object)."}, + {"get_candidate_ver",PkgDepCacheGetCandidateVer,METH_VARARGS, + "get_candidate_ver(pkg: apt_pkg.Package) -> apt_pkg.Version\n\n" + "Return the candidate version for the package, normally the version\n" + "with the highest pin (changeable using set_candidate_ver)."}, + {"set_candidate_ver",PkgDepCacheSetCandidateVer,METH_VARARGS, + "set_candidate_ver(pkg: apt_pkg.Package, ver: apt_pkg.Version) -> bool\n\n" + "Set the candidate version of 'pkg' to 'ver'."}, + {"set_candidate_release",PkgDepCacheSetCandidateRelease,METH_VARARGS, + "set_candidate_release(pkg: apt_pkg.Package, ver: apt_pkg.Version, rel: string) -> bool\n\n" + "Sets not only the candidate version 'ver' for package 'pkg', " + "but walks also down the dependency tree and checks if it is required " + "to set the candidate of the dependency to a version from the given " + "release string 'rel', too."}, + + // global cache operations + {"upgrade",PkgDepCacheUpgrade,METH_VARARGS, + "upgrade([dist_upgrade: bool = True]) -> bool\n\n" + "Mark the packages for upgrade under the same conditions apt-get\n" + "upgrade does. If 'dist_upgrade' is True, also allow packages to\n" + "be upgraded if they require installation/removal of other packages;\n" + "just like apt-get dist-upgrade."}, + {"fix_broken",PkgDepCacheFixBroken,METH_VARARGS, + "fix_broken() -> bool\n\n" + "Fix broken packages."}, + {"read_pinfile",PkgDepCacheReadPinFile,METH_VARARGS, + "read_pinfile([file: str])\n\n" + "Read the pin policy"}, + {"minimize_upgrade",PkgDepCacheMinimizeUpgrade, METH_VARARGS, + "minimize_upgrade() -> bool\n\n" + "Go over the entire set of packages and try to keep each package\n" + "marked for upgrade. If a conflict is generated then the package\n" + "is restored."}, + // Policy + {"phasing_applied",PkgDepCachePhasingApplied,METH_VARARGS, + "phasing_applied(pkg: apt_pkg.Package) -> bool\n\n" + "Check if the phased update is ready.\n" + "return false if this is a phased update that is not yet ready for us.\n"}, + // Manipulators + {"mark_keep",PkgDepCacheMarkKeep,METH_VARARGS, + "mark_keep(pkg: apt_pkg.Package)\n\n" + "Mark package to be kept."}, + {"mark_delete",PkgDepCacheMarkDelete,METH_VARARGS, + "mark_delete(pkg: apt_pkg.Package[, purge: bool = False])\n\n" + "Mark package for deletion, and if 'purge' is True also for purging."}, + {"mark_install",PkgDepCacheMarkInstall,METH_VARARGS, + "mark_install(pkg: apt_pkg.Package[, auto_inst=True, from_user=True])\n\n" + "Mark the package for installation. The parameter 'auto_inst' controls\n" + "whether the dependencies of the package are marked for installation\n" + "as well. The parameter 'from_user' controls whether the package is\n" + "registered as NOT automatically installed."}, + {"mark_auto",PkgDepCacheMarkAuto,METH_VARARGS, + "mark_auto(pkg: apt_pkg.Package, auto: bool)\n\n" + "Mark package as automatically installed (if auto=True),\n" + "or as not automatically installed (if auto=False)."}, + {"set_reinstall",PkgDepCacheSetReInstall,METH_VARARGS, + "set_reinstall(pkg: apt_pkg.Package, reinstall: bool)\n\n" + "Set whether the package should be reinstalled (reinstall = True or False)."}, + // state information + {"is_upgradable",PkgDepCacheIsUpgradable,METH_VARARGS, + "is_upgradable(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is upgradable."}, + {"is_now_broken",PkgDepCacheIsNowBroken,METH_VARARGS, + "is_now_broken(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is broken, taking marked changes into account."}, + {"is_inst_broken",PkgDepCacheIsInstBroken,METH_VARARGS, + "is_inst_broken(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is broken, ignoring marked changes."}, + {"is_garbage",PkgDepCacheIsGarbage,METH_VARARGS, + "is_garbage(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is garbage, i.e. whether it is automatically\n" + "installed and the reverse dependencies are not installed anymore."}, + {"is_auto_installed",PkgDepCacheIsAutoInstalled,METH_VARARGS, + "is_auto_installed(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is marked as automatically installed."}, + {"marked_install",PkgDepCacheMarkedInstall,METH_VARARGS, + "marked_install(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is marked for installation."}, + {"marked_upgrade",PkgDepCacheMarkedUpgrade,METH_VARARGS, + "marked_upgrade(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is marked for upgrade."}, + {"marked_delete",PkgDepCacheMarkedDelete,METH_VARARGS, + "marked_delete(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is marked for removal."}, + {"marked_keep",PkgDepCacheMarkedKeep,METH_VARARGS, + "marked_keep(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package should be kept."}, + {"marked_reinstall",PkgDepCacheMarkedReinstall,METH_VARARGS, + "marked_reinstall(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is marked for re-installation."}, + {"marked_downgrade",PkgDepCacheMarkedDowngrade,METH_VARARGS, + "marked_downgrade(pkg: apt_pkg.Package) -> bool\n\n" + "Check whether the package is marked for downgrade."}, + // Action + {"commit", PkgDepCacheCommit, METH_VARARGS, + "commit(acquire_progress, install_progress)\n\n" + "Commit all the marked changes. This method takes two arguments,\n" + "'acquire_progress' takes an apt.progress.base.AcquireProgress\n" + "object and 'install_progress' an apt.progress.base.InstallProgress\n" + "object."}, + {} +}; + +#define depcache (GetCpp(Self)) +static PyObject *PkgDepCacheGetKeepCount(PyObject *Self,void*) { + return MkPyNumber(depcache->KeepCount()); +} +static PyObject *PkgDepCacheGetInstCount(PyObject *Self,void*) { + return MkPyNumber(depcache->InstCount()); +} +static PyObject *PkgDepCacheGetDelCount(PyObject *Self,void*) { + return MkPyNumber(depcache->DelCount()); +} +static PyObject *PkgDepCacheGetBrokenCount(PyObject *Self,void*) { + return MkPyNumber(depcache->BrokenCount()); +} +static PyObject *PkgDepCacheGetUsrSize(PyObject *Self,void*) { + return MkPyNumber(depcache->UsrSize()); +} +static PyObject *PkgDepCacheGetDebSize(PyObject *Self,void*) { + return MkPyNumber(depcache->DebSize()); +} +#undef depcache + +static PyObject *PkgDepCacheGetPolicy(PyObject *Self,void*) { + PyObject *Owner = GetOwner(Self); + pkgDepCache *DepCache = GetCpp(Self); + pkgPolicy *Policy = (pkgPolicy *)&DepCache->GetPolicy(); + CppPyObject *PyPolicy = + CppPyObject_NEW(Owner,&PyPolicy_Type,Policy); + // Policy should not be deleted, it is managed by CacheFile. + PyPolicy->NoDelete = true; + return PyPolicy; +} + + +static PyGetSetDef PkgDepCacheGetSet[] = { + {"broken_count",PkgDepCacheGetBrokenCount,0, + "The number of packages with broken dependencies in the cache."}, + {"deb_size",PkgDepCacheGetDebSize,0, + "The size of the packages which are needed for the changes to be\n" + "applied."}, + {"del_count",PkgDepCacheGetDelCount,0, + "The number of packages marked for removal."}, + {"inst_count",PkgDepCacheGetInstCount,0, + "The number of packages marked for installation."}, + {"keep_count",PkgDepCacheGetKeepCount,0, + "The number of packages marked for keep."}, + {"usr_size",PkgDepCacheGetUsrSize,0, + "The amount of space required for installing/removing the packages,\n" + "i.e. the Installed-Size of all packages marked for installation\n" + "minus the Installed-Size of all packages for removal."}, + {"policy",PkgDepCacheGetPolicy,0, + "The apt_pkg.Policy object used by this cache."}, + {} +}; + +static PyObject *PkgDepCacheNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) +{ + PyObject *Owner; + char *kwlist[] = {"cache", 0}; + if (PyArg_ParseTupleAndKeywords(Args,kwds,"O!",kwlist,&PyCache_Type, + &Owner) == 0) + return 0; + + + // the owner of the Python cache object is a cachefile object, get it + PyObject *CacheFilePy = GetOwner(Owner); + // get the pkgCacheFile from the cachefile + pkgCacheFile *CacheF = GetCpp(CacheFilePy); + // and now the depcache + pkgDepCache *depcache = (pkgDepCache *)(*CacheF); + + CppPyObject *DepCachePyObj; + DepCachePyObj = CppPyObject_NEW(Owner,type,depcache); + + // Do not delete the underlying pointer, it is managed by the cachefile. + DepCachePyObj->NoDelete = true; + + return HandleErrors(DepCachePyObj); +} + +static char *doc_PkgDepCache = "DepCache(cache: apt_pkg.Cache)\n\n" + "A DepCache() holds extra information on the state of the packages.\n\n" + "The parameter 'cache' refers to an apt_pkg.Cache() object."; +PyTypeObject PyDepCache_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.DepCache", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC), + doc_PkgDepCache, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgDepCacheMethods, // tp_methods + 0, // tp_members + PkgDepCacheGetSet, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PkgDepCacheNew, // tp_new +}; + + + + + /*}}}*/ + +#undef VALIDATE_ITERATOR +#define VALIDATE_ITERATOR(I) (void) 0 // FIXME: Need access to depcache of pkgProblemResolver + +// pkgProblemResolver Class /*{{{*/ +// --------------------------------------------------------------------- +static PyObject *PkgProblemResolverNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) +{ + PyObject *Owner; + char *kwlist[] = {"depcache",0}; + if (PyArg_ParseTupleAndKeywords(Args,kwds,"O!",kwlist,&PyDepCache_Type, + &Owner) == 0) + return 0; + + pkgDepCache *depcache = GetCpp(Owner); + pkgProblemResolver *fixer = new pkgProblemResolver(depcache); + CppPyObject *PkgProblemResolverPyObj; + PkgProblemResolverPyObj = CppPyObject_NEW(Owner, + type, + fixer); + HandleErrors(PkgProblemResolverPyObj); + + return PkgProblemResolverPyObj; +} + + +static PyObject *PkgProblemResolverResolve(PyObject *Self,PyObject *Args) +{ + bool res; + pkgProblemResolver *fixer = GetCpp(Self); + + char brokenFix=1; + if (PyArg_ParseTuple(Args,"|b",&brokenFix) == 0) + return 0; + + Py_BEGIN_ALLOW_THREADS + res = fixer->Resolve(brokenFix); + Py_END_ALLOW_THREADS + + return HandleErrors(PyBool_FromLong(res)); +} + +static PyObject *PkgProblemResolverResolveByKeep(PyObject *Self,PyObject *Args) +{ + bool res; + pkgProblemResolver *fixer = GetCpp(Self); + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + Py_BEGIN_ALLOW_THREADS + res = fixer->ResolveByKeep(); + Py_END_ALLOW_THREADS + + return HandleErrors(PyBool_FromLong(res)); +} + +static PyObject *PkgProblemResolverProtect(PyObject *Self,PyObject *Args) +{ + pkgProblemResolver *fixer = GetCpp(Self); + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + fixer->Protect(Pkg); + Py_INCREF(Py_None); + return HandleErrors(Py_None); + +} +static PyObject *PkgProblemResolverRemove(PyObject *Self,PyObject *Args) +{ + pkgProblemResolver *fixer = GetCpp(Self); + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + fixer->Remove(Pkg); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyObject *PkgProblemResolverClear(PyObject *Self,PyObject *Args) +{ + pkgProblemResolver *fixer = GetCpp(Self); + PyObject *PackageObj; + if (PyArg_ParseTuple(Args,"O!",&PyPackage_Type,&PackageObj) == 0) + return 0; + pkgCache::PkgIterator &Pkg = GetCpp(PackageObj); + VALIDATE_ITERATOR(Pkg); + fixer->Clear(Pkg); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyObject *PkgProblemResolverKeepPhasedUpdates(PyObject *Self,PyObject *Args) +{ + bool res; + pkgProblemResolver *fixer = GetCpp(Self); + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + Py_BEGIN_ALLOW_THREADS + res = fixer->KeepPhasedUpdates(); + Py_END_ALLOW_THREADS + + return HandleErrors(PyBool_FromLong(res)); +} + + +static PyMethodDef PkgProblemResolverMethods[] = +{ + // config + {"protect", PkgProblemResolverProtect, METH_VARARGS, + "protect(pkg: apt_pkg.Package)\n\n" + "Mark the package as protected in the resolver, meaning that its\n" + "state will not be changed."}, + {"remove", PkgProblemResolverRemove, METH_VARARGS, + "remove(pkg: apt_pkg.Package)\n\n" + "Mark the package for removal in the resolver."}, + {"clear", PkgProblemResolverClear, METH_VARARGS, + "clear(pkg: apt_pkg.Package)\n\n" + "Revert the actions done by protect()/remove() on the package."}, + + // Actions + {"resolve", PkgProblemResolverResolve, METH_VARARGS, + "resolve([fix_broken: bool = True]) -> bool\n\n" + "Try to intelligently resolve problems by installing and removing\n" + "packages. If 'fix_broken' is True, apt will try to repair broken\n" + "dependencies of installed packages."}, + {"resolve_by_keep", PkgProblemResolverResolveByKeep, METH_VARARGS, + "resolve_by_keep() -> bool\n\n" + "Try to resolve problems only by using keep."}, + {"keep_phased_updates", PkgProblemResolverKeepPhasedUpdates, METH_VARARGS, + "keep_phased_updates() -> bool\n\n" + "Hold back upgrades to phased versions of already installed\n" + "packages, unless they are security updates."}, + {} +}; + +static const char *problemresolver_doc = + "ProblemResolver(depcache: apt_pkg.DepCache)\n\n" + "ProblemResolver objects take care of resolving problems\n" + "with dependencies. They mark packages for installation/\n" + "removal and try to satisfy all dependencies."; +PyTypeObject PyProblemResolver_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.ProblemResolver", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr,// tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC), + problemresolver_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgProblemResolverMethods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PkgProblemResolverNew, // tp_new +}; + + /*}}}*/ + +// pkgActionGroup Class /*{{{*/ +// --------------------------------------------------------------------- + +static const char *actiongroup_release_doc = + "release()\n\n" + "End the scope of this action group. If this is the only action\n" + "group bound to the cache, this will cause any deferred cleanup\n" + "actions to be performed."; +static PyObject *PkgActionGroupRelease(PyObject *Self,PyObject *Args) +{ + pkgDepCache::ActionGroup *ag = GetCpp(Self); + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + ag->release(); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static const char *actiongroup__enter__doc = + "__enter__() -> ActionGroup\n\n" + "A dummy action which just returns the object itself, so it can\n" + "be used as a context manager."; +static PyObject *PkgActionGroupEnter(PyObject *Self,PyObject *Args) { + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + Py_INCREF(Self); + return Self; +} + +static const char *actiongroup__exit__doc = + "__exit__(*excinfo) -> bool\n\n" + "Same as release(), but for use as a context manager."; +static PyObject *PkgActionGroupExit(PyObject *Self,PyObject *Args) { + pkgDepCache::ActionGroup *ag = GetCpp(Self); + if (ag != NULL) + ag->release(); + Py_RETURN_FALSE; +} + +static PyMethodDef PkgActionGroupMethods[] = +{ + {"release", PkgActionGroupRelease, METH_VARARGS, actiongroup_release_doc}, + {"__enter__", PkgActionGroupEnter, METH_VARARGS, actiongroup__enter__doc}, + {"__exit__", PkgActionGroupExit, METH_VARARGS, actiongroup__exit__doc}, + {} +}; + +static PyObject *PkgActionGroupNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) +{ + PyObject *Owner; + char *kwlist[] = {"depcache", 0}; + if (PyArg_ParseTupleAndKeywords(Args,kwds,"O!",kwlist,&PyDepCache_Type, + &Owner) == 0) + return 0; + + pkgDepCache *depcache = GetCpp(Owner); + pkgDepCache::ActionGroup *group = new pkgDepCache::ActionGroup(*depcache); + CppPyObject *PkgActionGroupPyObj; + PkgActionGroupPyObj = CppPyObject_NEW(Owner, + type, + group); + HandleErrors(PkgActionGroupPyObj); + + return PkgActionGroupPyObj; + +} + +static char *doc_PkgActionGroup = "ActionGroup(depcache)\n\n" + "Create a new ActionGroup() object. The parameter *depcache* refers to an\n" + "apt_pkg.DepCache() object.\n\n" + "ActionGroups disable certain cleanup actions, so modifying many packages\n" + "is much faster.\n\n" + "ActionGroup() can also be used with the 'with' statement, but be aware\n" + "that the ActionGroup() is active as soon as it is created, and not just\n" + "when entering the context. This means you can write::\n\n" + " with apt_pkg.ActionGroup(depcache):\n" + " depcache.markInstall(pkg)\n\n" + "Once the block of the with statement is left, the action group is \n" + "automatically released from the cache."; + + +PyTypeObject PyActionGroup_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.ActionGroup", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC), + doc_PkgActionGroup, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgActionGroupMethods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PkgActionGroupNew, // tp_new +}; + + + + /*}}}*/ diff --git a/python/generic.cc b/python/generic.cc new file mode 100644 index 0000000..16f1cce --- /dev/null +++ b/python/generic.cc @@ -0,0 +1,122 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: generic.cc,v 1.1.1.1 2001/02/20 06:32:01 jgg Exp $ +/* ###################################################################### + + generic - Some handy functions to make integration a tad simpler + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "generic.h" +using namespace std; + + +#include + /*}}}*/ + +// HandleErrors - This moves errors from _error to Python Exceptions /*{{{*/ +// --------------------------------------------------------------------- +/* We throw away all warnings and only propogate the first error. */ +PyObject *HandleErrors(PyObject *Res) +{ + string Err; + int errcnt = 0; + int wrncnt = 0; + while (_error->empty() == false) + { + string Msg; + bool Type = _error->PopMessage(Msg); + if (errcnt > 0 || wrncnt > 0) + Err.append(", "); + Err.append((Type == true ? "E:" : "W:")); + Err.append(Msg); + if (Type) + ++errcnt; + else + ++wrncnt; + } + if (errcnt > 0) + { + PyErr_SetString(PyAptError,Err.c_str()); + goto err; + } + else if (wrncnt > 0) + { + if (PyErr_WarnEx(PyAptWarning, Err.c_str(), 1) == -1) + goto err; + } + + return Res; +err: + if (Res != 0) + Py_DECREF(Res); + + return nullptr; +} + + /*}}}*/ +// ListToCharChar - Convert a list to an array of char char /*{{{*/ +// --------------------------------------------------------------------- +/* Caller must free the result. 0 on error. */ +const char **ListToCharChar(PyObject *List,bool NullTerm) +{ + // Convert the argument list into a char ** + int Length = PySequence_Length(List); + const char **Res = new const char *[Length + (NullTerm == true?1:0)]; + for (int I = 0; I != Length; I++) + { + PyObject *Itm = PySequence_GetItem(List,I); + Res[I] = PyObject_AsString(Itm); + if (Res[I] == nullptr) { + delete [] Res; + return nullptr; + } + } + if (NullTerm == true) + Res[Length] = 0; + return Res; +} + /*}}}*/ +// CharCharToList - Inverse of the above /*{{{*/ +// --------------------------------------------------------------------- +/* Zero size indicates the list is Null terminated. */ +PyObject *CharCharToList(const char **List,unsigned long Size) +{ + if (Size == 0) + { + for (const char **I = List; *I != 0; I++) + Size++; + } + + // Convert the whole configuration space into a list + PyObject *PList = PyList_New(Size); + for (unsigned long I = 0; I != Size; I++, List++) + PyList_SetItem(PList,I,CppPyString(*List)); + + return PList; +} + /*}}}*/ + +int PyApt_Filename::init(PyObject *object) +{ + this->object = NULL; + this->path = NULL; + +#if PY_MAJOR_VERSION < 3 || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION < 2) + this->path = PyObject_AsString(object); + return this->path ? 1 : 0; +#else + if (PyUnicode_Check(object)) { + object = PyUnicode_EncodeFSDefault(object); + } else if (PyBytes_Check(object)) { + Py_INCREF(object); + } else { + return 0; + } + + this->object = object; + this->path = PyBytes_AS_STRING(this->object); + return 1; +#endif +} diff --git a/python/generic.h b/python/generic.h new file mode 100644 index 0000000..60f9531 --- /dev/null +++ b/python/generic.h @@ -0,0 +1,336 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: generic.h,v 1.4 2002/03/10 05:45:34 mdz Exp $ +/* ###################################################################### + + generic - Some handy functions to make integration a tad simpler + + Python needs this little _HEAD tacked onto the front of the object.. + This complicates the integration with C++. We use some templates to + make that quite transparent to us. It would have been nice if Python + internally used a page from the C++ ref counting book to hide its little + header from the world, but it doesn't. + + The CppPyObject has the target object and the Python header, this is + needed to ensure proper alignment. + GetCpp returns the C++ object from a PyObject. + CppPyObject_NEW creates the Python object and then uses placement new + to init the C++ class.. This is good for simple situations and as an + example on how to do it in other more specific cases. + CppPyObject_Dealloc should be used in the Type as the destructor + function. + HandleErrors converts errors from the internal _error stack into Python + exceptions and makes sure the _error stack is empty. + + ##################################################################### */ + /*}}}*/ +#ifndef GENERIC_H +#define GENERIC_H + +#include +#include +#include +#include +#include + +/** + * Exception class for almost all Python errors + */ +extern PyObject *PyAptError; +extern PyObject *PyAptWarning; +/** + * Exception class for invalidated cache objects. + */ +extern PyObject *PyAptCacheMismatchError; + +#if PYTHON_API_VERSION < 1013 +typedef int Py_ssize_t; +#endif + +/* Define compatibility for Python 3. + * + * We will use the names PyString_* to refer to the default string type + * of the current Python version (PyString on 2.X, PyUnicode on 3.X). + * + * When we really need unicode strings, we will use PyUnicode_* directly, as + * long as it exists in Python 2 and Python 3. + * + * When we want bytes in Python 3, we use PyBytes*_ instead of PyString_* and + * define aliases from PyBytes_* to PyString_* for Python 2. + */ + +#if PY_MAJOR_VERSION >= 3 +#define PyString_Check PyUnicode_Check +#define PyString_FromString PyUnicode_FromString +#define PyString_FromStringAndSize PyUnicode_FromStringAndSize +#define PyString_AsString PyUnicode_AsString +#define PyString_FromFormat PyUnicode_FromFormat +#define PyString_Type PyUnicode_Type +#define PyInt_Check PyLong_Check +#define PyInt_AsLong PyLong_AsLong +#define PyInt_FromLong PyLong_FromLong +#endif + +static inline const char *PyUnicode_AsString(PyObject *op) { + // Convert to bytes object, using the default encoding. +#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 + return PyUnicode_AsUTF8(op); +#else + // Use Python-internal API, there is no other way to do this + // without a memory leak. + PyObject *bytes = _PyUnicode_AsDefaultEncodedString(op, 0); + return bytes ? PyBytes_AS_STRING(bytes) : 0; +#endif +} + +// Convert any type of string based object to a const char. +#if PY_MAJOR_VERSION < 3 +static inline const char *PyObject_AsString(PyObject *object) { + if (PyBytes_Check(object)) + return PyBytes_AsString(object); + else if (PyUnicode_Check(object)) + return PyUnicode_AsString(object); + else + PyErr_SetString(PyExc_TypeError, "Argument must be str."); + return 0; +} +#else +static inline const char *PyObject_AsString(PyObject *object) { + if (PyUnicode_Check(object) == 0) { + PyErr_SetString(PyExc_TypeError, "Argument must be str."); + return 0; + } + return PyUnicode_AsString(object); +} +#endif + +template struct CppPyObject : public PyObject +{ + // We are only using CppPyObject and friends as dumb structs only, ie the + // c'tor is never called. + // However if T doesn't have a default c'tor C++ doesn't generate one for + // CppPyObject (since it can't know how it should initialize Object). + // + // This causes problems then in CppPyObject, for which C++ can't create + // a c'tor that calls the base class c'tor (which causes a compilation + // error). + // So basically having the c'tor here removes the need for T to have a + // default c'tor, which is not always desireable. + CppPyObject() { }; + + // The owner of the object. The object keeps a reference to it during its + // lifetime. + PyObject *Owner; + + // Flag which causes the underlying object to not be deleted. + bool NoDelete; + + // The underlying C++ object. + T Object; +}; + +template +inline T &GetCpp(PyObject *Obj) +{ + return ((CppPyObject *)Obj)->Object; +} + +template +inline PyObject *GetOwner(PyObject *Obj) +{ + return ((CppPyObject *)Obj)->Owner; +} + + +template +inline CppPyObject *CppPyObject_NEW(PyObject *Owner,PyTypeObject *Type) +{ + #ifdef ALLOC_DEBUG + std::cerr << "=== ALLOCATING " << Type->tp_name << "+ ===\n"; + #endif + CppPyObject *New = (CppPyObject*)Type->tp_alloc(Type, 0); + new (&New->Object) T; + New->Owner = Owner; + Py_XINCREF(Owner); + return New; +} + +template +inline CppPyObject *CppPyObject_NEW(PyObject *Owner, PyTypeObject *Type,A const &Arg) +{ + #ifdef ALLOC_DEBUG + std::cerr << "=== ALLOCATING " << Type->tp_name << "+ ===\n"; + #endif + CppPyObject *New = (CppPyObject*)Type->tp_alloc(Type, 0); + new (&New->Object) T(Arg); + New->Owner = Owner; + Py_XINCREF(Owner); + return New; +} + +// Traversal and Clean for objects +template +int CppTraverse(PyObject *self, visitproc visit, void* arg) { + Py_VISIT(((CppPyObject *)self)->Owner); + return 0; +} + +template +int CppClear(PyObject *self) { + Py_CLEAR(((CppPyObject *)self)->Owner); + return 0; +} + +template +void CppDealloc(PyObject *iObj) +{ + #ifdef ALLOC_DEBUG + std::cerr << "=== DEALLOCATING " << iObj->ob_type->tp_name << "+ ===\n"; + #endif + if (iObj->ob_type->tp_flags & Py_TPFLAGS_HAVE_GC) + PyObject_GC_UnTrack(iObj); + CppPyObject *Obj = (CppPyObject *)iObj; + if (!((CppPyObject*)Obj)->NoDelete) + Obj->Object.~T(); + CppClear(iObj); + iObj->ob_type->tp_free(iObj); +} + + +template +void CppDeallocPtr(PyObject *iObj) +{ + #ifdef ALLOC_DEBUG + std::cerr << "=== DEALLOCATING " << iObj->ob_type->tp_name << "*+ ===\n"; + #endif + if (iObj->ob_type->tp_flags & Py_TPFLAGS_HAVE_GC) + PyObject_GC_UnTrack(iObj); + CppPyObject *Obj = (CppPyObject *)iObj; + if (!((CppPyObject*)Obj)->NoDelete) { + delete Obj->Object; + Obj->Object = NULL; + } + CppClear(iObj); + iObj->ob_type->tp_free(iObj); +} + +inline PyObject *CppPyString(const std::string &Str) +{ + return PyString_FromStringAndSize(Str.c_str(),Str.length()); +} + +inline PyObject *CppPyString(const char *Str) +{ + if (Str == 0) + return PyString_FromString(""); + return PyString_FromString(Str); +} + +inline PyObject *CppPyLocaleString(const std::string &Str) +{ + char const * const codeset = nl_langinfo(CODESET); + return PyUnicode_Decode(Str.c_str(), Str.length(), codeset, "replace"); +} + +#if PY_MAJOR_VERSION >= 3 +static inline PyObject *CppPyPath(const std::string &path) +{ + return PyUnicode_DecodeFSDefaultAndSize(path.c_str(), path.length()); +} + +static inline PyObject *CppPyPath(const char *path) +{ + if (path == nullptr) + path = ""; + return PyUnicode_DecodeFSDefault(path); +} +#else +template static inline PyObject *CppPyPath(T path) { + return CppPyString(path); +} +#endif + +// Convert _error into Python exceptions +PyObject *HandleErrors(PyObject *Res = 0); + +// Convert a list of strings to a char ** +const char **ListToCharChar(PyObject *List,bool NullTerm = false); +PyObject *CharCharToList(const char **List,unsigned long Size = 0); + +/* Happy number conversion, thanks to overloading */ +inline PyObject *MkPyNumber(unsigned long long o) { return PyLong_FromUnsignedLongLong(o); } +inline PyObject *MkPyNumber(unsigned long o) { return PyLong_FromUnsignedLong(o); } +inline PyObject *MkPyNumber(unsigned int o) { return PyLong_FromUnsignedLong(o); } +inline PyObject *MkPyNumber(unsigned short o) { return PyInt_FromLong(o); } +inline PyObject *MkPyNumber(unsigned char o) { return PyInt_FromLong(o); } + +inline PyObject *MkPyNumber(long long o) { return PyLong_FromLongLong(o); } +inline PyObject *MkPyNumber(long o) { return PyInt_FromLong(o); } +inline PyObject *MkPyNumber(int o) { return PyInt_FromLong(o); } +inline PyObject *MkPyNumber(short o) { return PyInt_FromLong(o); } +inline PyObject *MkPyNumber(signed char o) { return PyInt_FromLong(o); } + +inline PyObject *MkPyNumber(double o) { return PyFloat_FromDouble(o); } + +# define _PyAptObject_getattro 0 + + +/** + * Magic class for file name handling + * + * This manages decoding file names from Python objects; bytes and unicode + * objects. On Python 2, this does the same conversion as PyObject_AsString, + * on Python3, it uses PyUnicode_EncodeFSDefault for unicode objects. + */ +class PyApt_Filename { +public: + PyObject *object; + const char *path; + + PyApt_Filename() { + object = NULL; + path = NULL; + } + + int init(PyObject *object); + + ~PyApt_Filename() { + Py_XDECREF(object); + } + + static int Converter(PyObject *object, void *out) { + return static_cast(out)->init(object); + } + + operator const char *() { + return path; + } + operator const std::string() { + return path; + } + + const char *operator=(const char *path) { + return this->path = path; + } +}; + + +/** + * Basic smart pointer to hold initial objects. + * + * This is like a std::unique_ptr to some extend, + * but it is for initialization only, and hence will also clear out any members + * in case it deletes the instance (the error case). + */ +template struct PyApt_UniqueObject { + T *self; + explicit PyApt_UniqueObject(T *self) : self(self) { } + ~PyApt_UniqueObject() { reset(NULL); } + void reset(T *newself) { if (clear && self && Py_TYPE(self)->tp_clear) Py_TYPE(self)->tp_clear(self); Py_XDECREF(self); self = newself; } + PyApt_UniqueObject operator =(PyApt_UniqueObject) = delete; + bool operator ==(void *other) { return self == other; } + T *operator ->() { return self; } + T *get() { return self; } + T *release() { T *ret = self; self = NULL; return ret; } +}; +#endif diff --git a/python/hashes.cc b/python/hashes.cc new file mode 100644 index 0000000..9f3fb46 --- /dev/null +++ b/python/hashes.cc @@ -0,0 +1,135 @@ +/* hashes.cc - Wrapper around apt-pkg's Hashes. + * + * Copyright 2009 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include +#include "generic.h" +#include "apt_pkgmodule.h" +#include + +static PyObject *hashes_new(PyTypeObject *type,PyObject *args, + PyObject *kwds) +{ + return CppPyObject_NEW(NULL, type); +} + +static int hashes_init(PyObject *self, PyObject *args, PyObject *kwds) +{ + PyObject *object = 0; + int Fd; + char *kwlist[] = {"object", NULL}; + + if (PyArg_ParseTupleAndKeywords(args, kwds, "|O:__init__", kwlist, + &object) == 0) + return -1; + if (object == 0) + return 0; + Hashes &hashes = GetCpp(self); + + if (PyBytes_Check(object) != 0) { + char *s; + Py_ssize_t len; + PyBytes_AsStringAndSize(object, &s, &len); + Py_BEGIN_ALLOW_THREADS + hashes.Add((const unsigned char*)s, len); + Py_END_ALLOW_THREADS + } + else if ((Fd = PyObject_AsFileDescriptor(object)) != -1) { + struct stat St; + bool err = false; + Py_BEGIN_ALLOW_THREADS + err = fstat(Fd, &St) != 0 || hashes.AddFD(Fd, St.st_size) == false; + Py_END_ALLOW_THREADS + if (err) { + PyErr_SetFromErrno(PyAptError); + return -1; + } + } + else { + PyErr_SetString(PyExc_TypeError, + "__init__() only understand bytes and files"); + return -1; + } + return 0; +} + +static PyObject *hashes_get_hashes(PyObject *self, void*) +{ + auto py = CppPyObject_NEW(nullptr, &PyHashStringList_Type); + + py->Object = GetCpp(self).GetHashStringList(); + return py; +} + + +static PyGetSetDef hashes_getset[] = { + {"hashes",hashes_get_hashes,0, + "A :class:`HashStringList` of all hashes.\n\n" + ".. versionadded:: 1.1"}, + {} +}; + +static char *hashes_doc = + "Hashes([object: (bytes, file)])\n\n" + "Calculate hashes for the given object. It can be used to create all\n" + "supported hashes for a file.\n\n" + "The parameter *object* can be a bytestring, an object providing the\n" + "fileno() method, or an integer describing a file descriptor."; + +PyTypeObject PyHashes_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Hashes", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE, + hashes_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + hashes_getset, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + hashes_init, // tp_init + 0, // tp_alloc + hashes_new, // tp_new +}; diff --git a/python/hashstring.cc b/python/hashstring.cc new file mode 100644 index 0000000..01f14a0 --- /dev/null +++ b/python/hashstring.cc @@ -0,0 +1,182 @@ +/* hashstring.cc - Wrapper around HashString + * + * Copyright 2009 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include +#include "generic.h" +#include "apt_pkgmodule.h" +#include + +static PyObject *hashstring_new(PyTypeObject *type,PyObject *Args, + PyObject *kwds) +{ + char *Type = NULL; + char *Hash = NULL; + char *kwlist[] = {"type", "hash", NULL}; + if (PyArg_ParseTupleAndKeywords(Args, kwds, "s|s:__new__", kwlist, &Type, + &Hash) == 0) + return 0; + CppPyObject *PyObj = CppPyObject_NEW(NULL, type); + if (Hash) + PyObj->Object = new HashString(Type,Hash); + else // Type is the combined form now (i.e. type:hash) + PyObj->Object = new HashString(Type); + return PyObj; +} + +static PyObject *hashstring_repr(PyObject *self) +{ + HashString *hash = GetCpp(self); + return PyString_FromFormat("<%s object: \"%s\">", self->ob_type->tp_name, + hash->toStr().c_str()); +} + +static PyObject *hashstring_str(PyObject *self) +{ + const HashString *hash = GetCpp(self); + return CppPyString(hash->toStr()); +} + +static PyObject *hashstring_get_hashtype(PyObject *self) +{ + const HashString *hash = GetCpp(self); + return CppPyString(hash->HashType()); +} + +static PyObject *hashstring_get_usable(PyObject *self) +{ + const HashString *hash = GetCpp(self); + return PyBool_FromLong(hash->usable()); +} + +static PyObject *hashstring_get_hashvalue(PyObject *self) +{ + const HashString *hash = GetCpp(self); + return CppPyString(hash->HashValue()); +} + +static char *hashstring_verify_file_doc = + "verify_file(filename: str) -> bool\n\n" + "Verify that the file indicated by filename matches the hash."; + +static PyObject *hashstring_verify_file(PyObject *self,PyObject *args) +{ + const HashString *hash = GetCpp(self); + char *filename; + if (PyArg_ParseTuple(args, "s:verify_file", &filename) == 0) + return 0; + return PyBool_FromLong(hash->VerifyFile(filename)); +} + +static PyMethodDef hashstring_methods[] = { + {"verify_file",hashstring_verify_file,METH_VARARGS, + hashstring_verify_file_doc}, + {NULL} +}; + +static PyGetSetDef hashstring_getset[] = { + {"hashtype",(getter)hashstring_get_hashtype,0, + "The type of the hash, as a string (possible: MD5Sum,SHA1,SHA256)."}, + {"hashvalue",(getter)hashstring_get_hashvalue,0, + "The value of the hash, as a hexadecimal string\n" + "\n" + ".. versionadded:: 1.9.0"}, + {"usable",(getter)hashstring_get_usable,0, + "True if the hashstring is a trusted hash type."}, + {NULL} +}; + +static PyObject *hashstring_richcompare(PyObject *obj1, PyObject *obj2, int op) +{ + if (!PyObject_TypeCheck(obj1, &PyHashString_Type)) + return PyErr_SetString(PyExc_TypeError, "Expected HashString"), nullptr; + if (!PyObject_TypeCheck(obj2, &PyHashString_Type)) + return PyErr_SetString(PyExc_TypeError, "Expected HashString"), nullptr; + + const HashString *a = GetCpp(obj1); + const HashString *b = GetCpp(obj2); + PyObject *result = Py_False; + + switch (op) { + case Py_LT: + case Py_GT: + result = Py_False; + break; + case Py_LE: + case Py_GE: + case Py_EQ: + result = *a == *b ? Py_True : Py_False; + break; + case Py_NE: + result = *a != *b ? Py_True : Py_False; + break; + } + + Py_INCREF(result); + return result; + } + +static char *hashstring_doc = + "HashString(type, hash) OR HashString('type:hash')\n\n" + "Create a new HashString object. The first form allows you to specify\n" + "a type and a hash, and the second form a single string where type and\n" + "hash are separated by a colon, e.g.::\n\n" + " HashString('MD5Sum', '6cc1b6e6655e3555ac47e5b5fe26d04e')\n\n" + "Valid options for 'type' are: MD5Sum, SHA1, SHA256."; +PyTypeObject PyHashString_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.HashString", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + hashstring_repr, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + hashstring_str, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE, + hashstring_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + hashstring_richcompare, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + hashstring_methods, // tp_methods + 0, // tp_members + hashstring_getset, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + hashstring_new, // tp_new +}; diff --git a/python/hashstringlist.cc b/python/hashstringlist.cc new file mode 100644 index 0000000..f25f502 --- /dev/null +++ b/python/hashstringlist.cc @@ -0,0 +1,220 @@ +/* hashstringlist.cc - Wrapper around apt-pkg's Hashes. + * + * Copyright 2015 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include +#include "generic.h" +#include "apt_pkgmodule.h" +#include + +static PyObject *hashstringlist_new(PyTypeObject *type, PyObject *args, + PyObject *kwds) +{ + return CppPyObject_NEW (nullptr, type); +} + +static int hashstringlist_init(PyObject *self, PyObject *args, + PyObject *kwds) +{ + char *kwlist[] = { NULL }; + + if (PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist) == 0) + return -1; + + return 0; +} + + +static const char hashstringlist_find_doc[] = + "find(type: str = \"\") -> HashString\n\n" + "Find a hash of the given type, or the best one, if the argument\n" + "is empty or not specified."; +static PyObject *hashstringlist_find(PyObject *self, PyObject *args) +{ + char *type = ""; + + if (PyArg_ParseTuple(args, "|s", &type) == 0) + return 0; + + const HashString *hsf = GetCpp(self).find(type); + if (hsf == nullptr) + return PyErr_Format(PyExc_KeyError, "Could not find hash type %s", type); + + + return HandleErrors(PyHashString_FromCpp(new HashString(*hsf), true, nullptr)); +} + +static const char hashstringlist_append_doc[] = + "append(object: HashString)\n\n" + "Append the given HashString to this list."; +static PyObject *hashstringlist_append(PyObject *self, PyObject *args) +{ + PyObject *o; + + if (PyArg_ParseTuple(args, "O!", &PyHashString_Type, &o) == 0) + return 0; + + GetCpp(self).push_back(*PyHashString_ToCpp(o)); + Py_RETURN_NONE; +} + +static const char hashstringlist_verify_file_doc[] = + "verify_file(filename: str) -> bool\n\n" + "Verify that the file with the given name matches all hashes in\n" + "the list."; +static PyObject *hashstringlist_verify_file(PyObject *self, PyObject *args) +{ + PyApt_Filename filename; + + if (PyArg_ParseTuple(args, "O&", PyApt_Filename::Converter, &filename) == 0) + return 0; + + bool res = GetCpp(self).VerifyFile(filename); + + PyObject *PyRes = PyBool_FromLong(res); + return HandleErrors(PyRes); +} + +static PyObject *hashstringlist_get_file_size(PyObject *self, void*) { + return MkPyNumber(GetCpp(self).FileSize()); +} +static PyObject *hashstringlist_get_usable(PyObject *self, void*) { + return PyBool_FromLong(GetCpp(self).usable()); +} + +static int hashstringlist_set_file_size(PyObject *self, PyObject *value, void *) { + if (PyLong_Check(value)) { + if (PyLong_AsUnsignedLongLong(value) == (unsigned long long) -1) { + return 1; + } + GetCpp(self).FileSize(PyLong_AsUnsignedLongLong(value)); + } else if (PyInt_Check(value)) { + if (PyInt_AsLong(value) < 0) { + if (!PyErr_Occurred()) + PyErr_SetString(PyExc_OverflowError, + "The file_size value must be positive"); + return 1; + } + GetCpp(self).FileSize(PyInt_AsLong(value)); + } else { + PyErr_SetString(PyExc_TypeError, + "The file_size value must be an integer or long"); + return 1; + } + + return 0; +} + +/* The same for groups */ +static Py_ssize_t hashstringlist_len(PyObject *self) +{ + return GetCpp (self).size(); +} + +static PyObject *hashstringlist_getitem(PyObject *iSelf, Py_ssize_t index) +{ + HashStringList &self = GetCpp(iSelf); + + if (index < 0 || (size_t) index >= self.size()) + return PyErr_Format(PyExc_IndexError, "Out of range: %zd", index); + + /* Copy over, safer than using a reference to the vector element */ + HashString *hs = new HashString; + (*hs) = *(self.begin() + index); + + return PyHashString_FromCpp(hs, true, nullptr); +} + +static PySequenceMethods hashstringlist_seq_methods = { + hashstringlist_len, + 0, // concat + 0, // repeat + hashstringlist_getitem, + 0, // slice + 0, // assign item + 0 // assign slice +}; + +static PyMethodDef hashstringlist_methods[] = +{ + {"verify_file",hashstringlist_verify_file,METH_VARARGS, + hashstringlist_verify_file_doc}, + {"find",hashstringlist_find,METH_VARARGS, + hashstringlist_find_doc}, + {"append",hashstringlist_append,METH_VARARGS, + hashstringlist_append_doc}, + {} +}; + +static PyGetSetDef hashstringlist_getset[] = { + {"file_size",hashstringlist_get_file_size,hashstringlist_set_file_size, + "If a file size is part of the list, return it, otherwise 0."}, + {"usable",hashstringlist_get_usable,nullptr, + "True if at least one safe/trusted hash is in the list."}, + {} +}; + + +static char *hashstringlist_doc = + "HashStringList()\n\n" + "Manage a list of HashStrings.\n\n" + "The list knows which hash is the best and provides convenience\n" + "methods for file verification.\n\n" + ".. versionadded:: 1.1"; + +PyTypeObject PyHashStringList_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.HashStringList", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &hashstringlist_seq_methods, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + hashstringlist_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + hashstringlist_methods, // tp_methods + 0, // tp_members + hashstringlist_getset, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + hashstringlist_init, // tp_init + 0, // tp_alloc + hashstringlist_new, // tp_new +}; diff --git a/python/indexfile.cc b/python/indexfile.cc new file mode 100644 index 0000000..423e2e3 --- /dev/null +++ b/python/indexfile.cc @@ -0,0 +1,130 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: indexfile.cc,v 1.2 2003/12/26 17:04:22 mdz Exp $ +/* ###################################################################### + + pkgIndexFile - Wrapper for the pkgIndexFilefunctions + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "generic.h" +#include "apt_pkgmodule.h" + +#include + +#include + +static PyObject *IndexFileArchiveURI(PyObject *Self,PyObject *Args) +{ + pkgIndexFile *File = GetCpp(Self); + PyApt_Filename path; + + if (PyArg_ParseTuple(Args, "O&", PyApt_Filename::Converter, &path) == 0) + return 0; + return HandleErrors(CppPyString(File->ArchiveURI(path).c_str())); +} + +static PyMethodDef IndexFileMethods[] = +{ + {"archive_uri",IndexFileArchiveURI,METH_VARARGS, + "archive_uri(path: str) -> str\n\n" + "Return the URI to the given path in the archive."}, + {} +}; + +#define File (GetCpp(Self)) +static PyObject *IndexFileGetLabel(PyObject *Self,void*) { + return CppPyString(File->GetType()->Label); +} +static PyObject *IndexFileGetDescribe(PyObject *Self,void*) { + return CppPyString(File->Describe().c_str()); +} +static PyObject *IndexFileGetExists(PyObject *Self,void*) { + return PyBool_FromLong((File->Exists())); +} +static PyObject *IndexFileGetHasPackages(PyObject *Self,void*) { + return PyBool_FromLong((File->HasPackages())); +} +static PyObject *IndexFileGetSize(PyObject *Self,void*) { + return MkPyNumber((File->Size())); +} +static PyObject *IndexFileGetIsTrusted(PyObject *Self,void*) { + return PyBool_FromLong((File->IsTrusted())); +} +#undef File + +#define S(x) (x ? x : "") +static PyObject *IndexFileRepr(PyObject *Self) +{ + pkgIndexFile *File = GetCpp(Self); + return PyString_FromFormat("", + S(File->GetType()->Label), File->Describe().c_str(), File->Exists(), + File->HasPackages(), File->Size(), + File->IsTrusted(), File->ArchiveURI("").c_str()); +} +#undef S + +static PyGetSetDef IndexFileGetSet[] = { + {"describe",IndexFileGetDescribe,0, + "A string describing the index file."}, + {"exists",IndexFileGetExists,0, + "A boolean value determining whether the index file exists."}, + {"has_packages",IndexFileGetHasPackages,0, + "A boolean value determining whether the index file has packages."}, + {"is_trusted",IndexFileGetIsTrusted,0, + "A boolean value determining whether the file can be trusted; e.g.\n" + "because it is from a source with a GPG signed Release file."}, + {"label",IndexFileGetLabel,0, + "The label of the index file."}, + {"size",IndexFileGetSize,0, + "The size of the files, measured in bytes."}, + {} +}; + +static const char *indexfile_doc = + "Represent an index file, i.e. package indexes, translation indexes,\n" + "and source indexes."; + +PyTypeObject PyIndexFile_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.IndexFile", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + // Not ..Ptr, because the pointer is managed somewhere else. + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + IndexFileRepr, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, // tp_flags + indexfile_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + IndexFileMethods, // tp_methods + 0, // tp_members + IndexFileGetSet, // tp_getset +}; + + + + diff --git a/python/lock.cc b/python/lock.cc new file mode 100644 index 0000000..009605e --- /dev/null +++ b/python/lock.cc @@ -0,0 +1,268 @@ +/* + * lock.cc - Context managers for implementing locking. + * + * Copyright 2009 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include +#include +#include +#include +#include +#include "generic.h" + +static PyObject *systemlock_exit(PyObject *self, PyObject *args) +{ + + PyObject *exc_type = 0; + PyObject *exc_value = 0; + PyObject *traceback = 0; + if (!PyArg_UnpackTuple(args, "__exit__", 3, 3, &exc_type, &exc_value, + &traceback)) { + return 0; + } + + if (_system->UnLock() == 0) { + // The unlock failed. If no exception happened within the suite, we + // will raise an error here. Otherwise, we just display the error, so + // Python can handle the original exception instead. + HandleErrors(); + if (exc_type == Py_None) + return NULL; + else + PyErr_WriteUnraisable(self); + } + // Return False, as required by the context manager protocol. + Py_RETURN_FALSE; +} + +static PyObject *systemlock_enter(PyObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + if (!_system->Lock()) + return HandleErrors(); + Py_INCREF(self); + return self; +} + +static PyObject *systemlock_new(PyTypeObject *type, PyObject *args, + PyObject *kwds) +{ + if (_system == 0) { + PyErr_SetString(PyExc_ValueError,"_system not initialized"); + return 0; + } + return PyType_GenericNew(type,args,kwds); +} + +static PyMethodDef systemlock_methods[] = { + {"__enter__",systemlock_enter,METH_VARARGS,"Lock the system."}, + {"__exit__",systemlock_exit,METH_VARARGS,"Unlock the system."}, + {NULL} +}; + +static char *systemlock_doc = "SystemLock()\n\n" + "Context manager for locking the package system. The lock is established\n" + "as soon as the method __enter__() is called. It is released when\n" + "__exit__() is called.\n\n" + "This should be used via the 'with' statement, for example:\n\n" + " with apt_pkg.SystemLock():\n" + " ...\n\n" + "Once the block is left, the lock is released automatically. The object\n" + "can be used multiple times:\n\n" + " lock = apt_pkg.SystemLock()\n" + " with lock:\n" + " ...\n" + " with lock:\n" + " ...\n\n"; + +PyTypeObject PySystemLock_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.SystemLock", // tp_name + 0, // tp_basicsize + 0, // tp_itemsize + // Methods + 0, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE), + systemlock_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + systemlock_methods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + systemlock_new, // tp_new +}; + + +/** + * File Based locking. + * + * The counter is increased by every call to filelock_enter() and decreased by + * every call to filelock_exit(). When the counter reaches 0, the underlying + * file descriptor is closed. + * + * Members: + * @member char* filename The name of the file + * @member int lock_count How many times we have locked it. + * @member int fd The filedescriptor returned by GetLock() or 0. + */ +struct filelock_object { + PyObject_HEAD + char *filename; + int lock_count; + int fd; +}; + +static PyObject *filelock_enter(filelock_object *self, PyObject *args) +{ + self->lock_count++; + // If we have no lock yet, get a lock. + if (self->lock_count == 1) { + self->fd = GetLock(self->filename, true); + if (self->fd == -1) { + self->lock_count--; + return HandleErrors(); + } + } + Py_INCREF(self); + return (PyObject *)self; +} + +static PyObject *filelock_exit(filelock_object *self, PyObject *args) +{ + // Count down the lock_count, if it is less than 0, reset it to 0. + self->lock_count--; + if (self->lock_count < 0) + self->lock_count = 0; + if (self->lock_count == 0 && self->fd != 0 && close(self->fd) == -1) { + return PyErr_SetFromErrno(PyExc_OSError); + } + Py_RETURN_FALSE; +} + +static PyObject *filelock_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + PyApt_Filename filename; + char *kwlist[] = {"filename", NULL}; + if (PyArg_ParseTupleAndKeywords(args, kwds, "O&:__init__", kwlist, + PyApt_Filename::Converter, + &filename) == 0) { + return NULL; + } + filelock_object *self = (filelock_object *)type->tp_alloc(type, 0); + // Copy the string into the object. + self->filename = new char[strlen(filename) + 1]; + strcpy(self->filename, filename); + return (PyObject *)self; +} + +static void filelock_dealloc(filelock_object *self) +{ + delete[] self->filename; + ((PyObject*)self)->ob_type->tp_free(self); +} + +static PyMethodDef filelock_methods[] = { + {"__enter__",(PyCFunction)filelock_enter,METH_VARARGS,"Lock the system."}, + {"__exit__",(PyCFunction)filelock_exit,METH_VARARGS,"Unlock the system."}, + {NULL} +}; + +static char *filelock_doc = "FileLock(filename: str)\n\n" + "Context manager for locking using a file. The lock is established\n" + "as soon as the method __enter__() is called. It is released when\n" + "__exit__() is called.\n\n" + "This should be used via the 'with' statement, for example:\n\n" + " with apt_pkg.FileLock(filename):\n" + " ...\n\n" + "Once the block is left, the lock is released automatically. The object\n" + "can be used multiple times:\n\n" + " lock = apt_pkg.FileLock(filename)\n" + " with lock:\n" + " ...\n" + " with lock:\n" + " ...\n\n"; + +PyTypeObject PyFileLock_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.FileLock", // tp_name + sizeof(filelock_object), // tp_basicsize + 0, // tp_itemsize + // Methods + destructor(filelock_dealloc), // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE), + filelock_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + filelock_methods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + filelock_new, // tp_new +}; diff --git a/python/metaindex.cc b/python/metaindex.cc new file mode 100644 index 0000000..abbcb8a --- /dev/null +++ b/python/metaindex.cc @@ -0,0 +1,117 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: metaindex.cc,v 1.2 2003/12/26 17:04:22 mdz Exp $ +/* ###################################################################### + + metaindex - Wrapper for the metaIndex functions + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "generic.h" +#include "apt_pkgmodule.h" + +#include + +#include + +static PyObject *MetaIndexGetURI(PyObject *Self,void*) { + metaIndex *meta = GetCpp(Self); + return CppPyString(meta->GetURI().c_str()); +} + +static PyObject *MetaIndexGetDist(PyObject *Self,void*) { + metaIndex *meta = GetCpp(Self); + return CppPyString(meta->GetDist().c_str()); +} + +static PyObject *MetaIndexGetIsTrusted(PyObject *Self,void*) { + metaIndex *meta = GetCpp(Self); + return PyBool_FromLong((meta->IsTrusted())); +} + +static PyObject *MetaIndexGetType(PyObject *Self,void*) { + metaIndex *meta = GetCpp(Self); + return CppPyString(meta->GetType()); +} + +static PyObject *MetaIndexGetIndexFiles(PyObject *Self,void*) { + metaIndex *meta = GetCpp(Self); + PyObject *List = PyList_New(0); + std::vector *indexFiles = meta->GetIndexFiles(); + for (std::vector::const_iterator I = indexFiles->begin(); + I != indexFiles->end(); I++) + { + CppPyObject *Obj; + Obj = CppPyObject_NEW(Self, &PyIndexFile_Type,*I); + // Do not delete pkgIndexFile*, they are managed by metaIndex. + Obj->NoDelete = true; + PyList_Append(List,Obj); + Py_DECREF(Obj); + } + return List; +} + +static PyGetSetDef MetaIndexGetSet[] = { + {"dist",MetaIndexGetDist,0,"The distribution, as a string."}, + {"index_files",MetaIndexGetIndexFiles,0, + "A list of all IndexFile objects associated with this meta index."}, + {"is_trusted",MetaIndexGetIsTrusted,0, + "A boolean value determining whether the file can be trusted."}, + {"uri",MetaIndexGetURI,0, + "The uri the meta index is located at."}, + {"type",MetaIndexGetType,0, + "The type of the meta index."}, + {} +}; + +#define S(x) (x ? x : "") +static PyObject *MetaIndexRepr(PyObject *Self) +{ + metaIndex *meta = GetCpp(Self); + return PyString_FromFormat("<%s object: type='%s', uri:'%s' dist='%s' " + "is_trusted='%i'>", Self->ob_type->tp_name, + S(meta->GetType()), meta->GetURI().c_str(), + meta->GetDist().c_str(), meta->IsTrusted()); +} +#undef S + + +static const char *metaindex_doc = + "Provide information on meta-indexes (i.e. Release files), such as\n" + "whether they are trusted or their URI."; + +PyTypeObject PyMetaIndex_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.MetaIndex", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + MetaIndexRepr, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + metaindex_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + MetaIndexGetSet, // tp_getset +}; diff --git a/python/orderlist.cc b/python/orderlist.cc new file mode 100644 index 0000000..d0ea184 --- /dev/null +++ b/python/orderlist.cc @@ -0,0 +1,317 @@ +/* + * orderlist.cc - Wrapper around pkgOrderList + * + * Copyright 2011 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include +#include "apt_pkgmodule.h" +#include "generic.h" +#include + +struct PyOrderList : CppPyObject { + pkgCache::PkgIterator current; + int nextIndex; +}; + +static PyObject *order_list_new(PyTypeObject *type,PyObject *args, + PyObject *kwds) +{ + PyObject *pyDepCache = NULL; + char *kwlist[] = {"depcache", NULL}; + if (PyArg_ParseTupleAndKeywords(args, kwds, "O!", kwlist, + &PyDepCache_Type, &pyDepCache) + == 0) + return 0; + + pkgDepCache *depCache = PyDepCache_ToCpp(pyDepCache); + return PyOrderList_FromCpp(new pkgOrderList(depCache), true, + pyDepCache); +} + +static const char order_list_append_doc[] = + "append(pkg: Package)\n\n" + "Append a package to the end of the list."; +static PyObject *order_list_append(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + PyObject *pyPackage = NULL; + if (PyArg_ParseTuple(args, "O!", &PyPackage_Type, &pyPackage) == 0) + return 0; + + list->push_back(PyPackage_ToCpp(pyPackage)); + Py_RETURN_NONE; +} + +static const char order_list_score_doc[] = + "score(pkg: Package) -> int\n\n" + "Return the score of the package."; +static PyObject *order_list_score(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + PyObject *pyPackage = NULL; + if (PyArg_ParseTuple(args, "O!", &PyPackage_Type, &pyPackage) == 0) + return 0; + + return MkPyNumber(list->Score(PyPackage_ToCpp(pyPackage))); +} + +static const char order_list_order_critical_doc[] = + "order_critical()\n\n" + "Order by PreDepends only (critical unpack order)."; +static PyObject *order_list_order_critical(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + if (PyArg_ParseTuple(args, "") == 0) + return 0; + + list->OrderCritical(); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static const char order_list_order_unpack_doc[] = + "order_unpack()\n\n" + "Order the packages for unpacking (see Debian Policy)."; +static PyObject *order_list_order_unpack(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + if (PyArg_ParseTuple(args, "") == 0) + return 0; + + list->OrderUnpack(); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static const char order_list_order_configure_doc[] = + "order_configure()\n\n" + "Order the packages for configuration (see Debian Policy)."; +static PyObject *order_list_order_configure(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + if (PyArg_ParseTuple(args, "") == 0) + return 0; + + list->OrderConfigure(); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static bool valid_flags(unsigned int flags) { + return (flags & ~pkgOrderList::Added + & ~pkgOrderList::AddPending + & ~pkgOrderList::Immediate + & ~pkgOrderList::Loop + & ~pkgOrderList::UnPacked + & ~pkgOrderList::Configured + & ~pkgOrderList::Removed + & ~pkgOrderList::InList + & ~pkgOrderList::After + & ~pkgOrderList::States) == 0; +} + +static const char order_list_flag_doc[] = + "flag(pkg: Package, flag: int[, unset_flags: int])\n\n" + "Flag the package, set flags in 'flag' and remove flags in\n" + "'unset_flags'."; +static PyObject *order_list_flag(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + + PyObject *pyPkg = NULL; + unsigned int flags = 0; + unsigned int unset_flags = 0; + if (PyArg_ParseTuple(args, "O!I|I", &PyPackage_Type, &pyPkg, + &flags, &unset_flags) == 0) + return 0; + + if (!valid_flags(flags)) + return PyErr_Format(PyExc_ValueError, "flags (%u) is" + " not a valid combination of flags.", + flags); + if (!valid_flags(unset_flags)) + return PyErr_Format(PyExc_ValueError, "unset_flags (%u) is" + " not a valid combination of flags.", + unset_flags); + + list->Flag(PyPackage_ToCpp(pyPkg), flags, unset_flags); + + Py_RETURN_NONE; +} + +static const char order_list_is_flag_doc[] = + "is_flag(pkg: Package, flag: int)\n\n" + "Check if the flag(s) are set."; +static PyObject *order_list_is_flag(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + PyObject *pyPkg = NULL; + unsigned int flags = 0; + if (PyArg_ParseTuple(args, "O!I", &PyPackage_Type, &pyPkg, + &flags) == 0) + return 0; + + if (!valid_flags(flags)) + return PyErr_Format(PyExc_ValueError, "flags (%u) is" + " not a valid combination of flags.", + flags); + + return PyBool_FromLong(list->IsFlag(PyPackage_ToCpp(pyPkg), flags)); +} + +static const char order_list_wipe_flags_doc[] = + "wipe_flags(flags: int)\n\n" + "Remove the flags in 'flags' from all packages in this list"; +static PyObject *order_list_wipe_flags(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + unsigned int flags = 0; + if (PyArg_ParseTuple(args, "I", &flags) == 0) + return 0; + + if (!valid_flags(flags)) + return PyErr_Format(PyExc_ValueError, "flags (%u) is" + " not a valid combination of flags.", + flags); + + list->WipeFlags(flags); + Py_RETURN_NONE; +} + +static const char order_list_is_now_doc[] = + "is_now(pkg: Package)\n\n" + "Check if the package is flagged for any state but removal."; +static PyObject *order_list_is_now(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + PyObject *pyPkg = NULL; + if (PyArg_ParseTuple(args, "O!", &PyPackage_Type, &pyPkg) == 0) + return 0; + + return PyBool_FromLong(list->IsNow(PyPackage_ToCpp(pyPkg))); +} + +static const char order_list_is_missing_doc[] = + "is_now(pkg: Package)\n\n" + "Check if the package is marked for install."; +static PyObject *order_list_is_missing(PyObject *self,PyObject *args) +{ + pkgOrderList *list = GetCpp(self); + PyObject *pyPkg = NULL; + if (PyArg_ParseTuple(args, "O!", &PyPackage_Type, &pyPkg) == 0) + return 0; + + return PyBool_FromLong(list->IsMissing(PyPackage_ToCpp(pyPkg))); +} + + +#define METHOD(name) {#name, order_list_##name, METH_VARARGS,\ + order_list_##name##_doc} + +static PyMethodDef order_list_methods[] = { + METHOD(append), + METHOD(score), + METHOD(order_critical), + METHOD(order_unpack), + METHOD(order_configure), + METHOD(flag), + METHOD(is_flag), + METHOD(is_now), + METHOD(is_missing), + METHOD(wipe_flags), + {} +}; + +static PyObject *order_list_seq_item(PyObject *self,Py_ssize_t index) +{ + pkgOrderList *list = GetCpp(self); + PyObject *owner = GetOwner(self); + PyObject *pycache = GetOwner(owner); + pkgCache *cache = PyCache_ToCpp(pycache); + + if (index < 0 || index >= list->size()) + return PyErr_Format(PyExc_IndexError, "Out of range: %zd", index); + + return PyPackage_FromCpp(pkgCache::PkgIterator(*cache, + *(list->begin() + index)), + true, owner); +} + +Py_ssize_t order_list_seq_length(PyObject *self) +{ + return GetCpp(self)->size(); +} + +static PySequenceMethods order_list_as_sequence = +{ + order_list_seq_length, // sq_length + 0, // sq_concat + 0, // sq_repeat + order_list_seq_item, // sq_item + 0, // sq_ass_item + 0, // sq_contains + 0, // sq_inplace_concat + 0 // sq_inplace_repeat +}; + +static const char order_list_doc[] = "OrderList(depcache: DepCache)\n\n" + "Sequence type for packages with special ordering methods."; +PyTypeObject PyOrderList_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.OrderList", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &order_list_as_sequence, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + order_list_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + order_list_methods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + order_list_new, // tp_new +}; diff --git a/python/pkgmanager.cc b/python/pkgmanager.cc new file mode 100644 index 0000000..2fb8e71 --- /dev/null +++ b/python/pkgmanager.cc @@ -0,0 +1,375 @@ +// Description /*{{{*/ +// $Id: acquire.cc,v 1.1 2003/06/03 03:03:23 mvo Exp $ +/* ###################################################################### + + PkgManager - Wrapper for the pkgPackageManager code + + ##################################################################### */ + +#include "generic.h" +#include "apt_pkgmodule.h" +#include "pkgrecords.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +static PyObject *PkgManagerGetArchives(PyObject *Self,PyObject *Args) +{ + pkgPackageManager *pm = GetCpp(Self); + PyObject *fetcher, *list, *recs; + + if (PyArg_ParseTuple(Args, "O!O!O!", + &PyAcquire_Type,&fetcher, + &PySourceList_Type, &list, + &PyPackageRecords_Type, &recs) == 0) + return 0; + + pkgAcquire *s_fetcher = GetCpp(fetcher); + pkgSourceList *s_list = GetCpp(list); + PkgRecordsStruct &s_records = GetCpp(recs); + + bool res = pm->GetArchives(s_fetcher, s_list, + &s_records.Records); + + return HandleErrors(PyBool_FromLong(res)); +} + +static PyObject *PkgManagerDoInstall(PyObject *Self,PyObject *Args) +{ + //PkgManagerStruct &Struct = GetCpp(Self); + pkgPackageManager *pm = GetCpp(Self); + int status_fd = -1; + + if (PyArg_ParseTuple(Args, "|i", &status_fd) == 0) + return 0; + + APT::Progress::PackageManagerProgressFd progress(status_fd); + + pkgPackageManager::OrderResult res = pm->DoInstall(&progress); + + return HandleErrors(MkPyNumber(res)); +} + +static PyObject *PkgManagerFixMissing(PyObject *Self,PyObject *Args) +{ + //PkgManagerStruct &Struct = GetCpp(Self); + pkgPackageManager *pm = GetCpp(Self); + + if (PyArg_ParseTuple(Args, "") == 0) + return 0; + + bool res = pm->FixMissing(); + + return HandleErrors(PyBool_FromLong(res)); +} + +static PyMethodDef PkgManagerMethods[] = +{ + {"get_archives",PkgManagerGetArchives,METH_VARARGS, + "get_archives(fetcher: Acquire, list: SourceList, recs: PackageRecords) -> bool\n\n" + "Download the packages marked for installation via the Acquire object\n" + "'fetcher', using the information found in 'list' and 'recs'."}, + {"do_install",PkgManagerDoInstall,METH_VARARGS, + "do_install(status_fd: int) -> int\n\n" + "Install the packages and return one of the class constants\n" + "RESULT_COMPLETED, RESULT_FAILED, RESULT_INCOMPLETE. The argument\n" + "status_fd can be used to specify a file descriptor that APT will\n" + "write status information on (see README.progress-reporting in the\n" + "apt source code for information on what will be written there)."}, + {"fix_missing",PkgManagerFixMissing,METH_VARARGS, + "fix_missing() -> bool\n\n" + "Fix the installation if a package could not be downloaded."}, + {} +}; + +static const char *packagemanager_doc = + "_PackageManager objects allow the fetching of packages marked for\n" + "installation and the installation of those packages.\n" + "This is an abstract base class that cannot be subclassed\n" + "in Python. The only subclass is apt_pkg.PackageManager. This\n" + "class is an implementation-detail and not part of the API."; +PyTypeObject PyPackageManager_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg._PackageManager", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flag, + packagemanager_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgManagerMethods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + 0, // tp_new +}; + + +struct CppPyRef { + PyObject *o; + CppPyRef(const CppPyRef &o) { Py_XINCREF(o); this->o = o; } + CppPyRef(PyObject *o) : o(o) {} + ~CppPyRef() { Py_XDECREF(o); } + operator PyObject *() const { return o; } + PyObject *operator->() const { return o; } +}; + +class PyPkgManager : public pkgDPkgPM { + bool res(CppPyRef result, const char* funcname) { + if (result == NULL) { + std::cerr << "Error in function: " << funcname << std::endl; + PyErr_Print(); + PyErr_Clear(); + return false; + } + return (result != NULL && + (result == Py_None || PyObject_IsTrue(result) == 1)); + } + + + PyObject *GetPyPkg(const PkgIterator &Pkg) { + PyObject *depcache = NULL; + PyObject *cache = NULL; + + depcache = GetOwner(pyinst); + if (depcache != NULL && PyDepCache_Check(depcache)) + cache = GetOwner(depcache); + + return PyPackage_FromCpp(Pkg, true, cache); + } + + /* Call through to Python */ + virtual bool Install(PkgIterator Pkg,std::string File) { + return res(PyObject_CallMethod(pyinst, "install", "(NN)", + GetPyPkg(Pkg), + CppPyString(File)), + "install"); + } + virtual bool Configure(PkgIterator Pkg) { + return res(PyObject_CallMethod(pyinst, "configure", "(N)", + GetPyPkg(Pkg)), + "configure"); + } + virtual bool Remove(PkgIterator Pkg,bool Purge = false) { + return res(PyObject_CallMethod(pyinst, "remove", "(NN)", + GetPyPkg(Pkg), + PyBool_FromLong(Purge)), + "remove" + ); + } + virtual bool Go(int StatusFd=-1) { + return res(PyObject_CallMethod(pyinst, "go", "(i)", + StatusFd), + "go"); + } + virtual void Reset() { + Py_XDECREF(PyObject_CallMethod(pyinst, "reset", NULL)); + } + +public: + /* Those call the protected functions from the parent class */ + bool callInstall(PkgIterator Pkg,std::string File) { return pkgDPkgPM::Install(Pkg, File); } + bool callRemove(PkgIterator Pkg, bool Purge) { return pkgDPkgPM::Remove(Pkg, Purge); } + bool callGo(int StatusFd=-1) { + APT::Progress::PackageManagerProgressFd progress(StatusFd); + return pkgDPkgPM::Go(&progress); + } + void callReset() { return pkgDPkgPM::Reset(); } + bool callConfigure(PkgIterator Pkg) { return pkgDPkgPM::Configure(Pkg); } + pkgOrderList *getOrderList() { return pkgPackageManager::List; } + + PyPkgManager(pkgDepCache *Cache) : pkgDPkgPM(Cache),pyinst(NULL) {}; + PyObject *pyinst; +}; + +static PyObject *PkgManagerNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) +{ + PyObject *Owner; + char *kwlist[] = {"depcache",0}; + if (PyArg_ParseTupleAndKeywords(Args,kwds,"O!",kwlist,&PyDepCache_Type, + &Owner) == 0) + return 0; + + PyPkgManager *pm = new PyPkgManager(GetCpp(Owner)); + + CppPyObject *PkgManagerObj = + CppPyObject_NEW(NULL, type,pm); + + pm->pyinst = PkgManagerObj; + + return PkgManagerObj; +} + + +static PyObject *PkgManagerInstall(PyObject *Self,PyObject *Args) +{ + PyPkgManager *pm = GetCpp(Self); + PyObject *pkg; + PyApt_Filename file; + + if (PyArg_ParseTuple(Args, "O!O&", &PyPackage_Type,&pkg, PyApt_Filename::Converter, &file) == 0) + return 0; + + return HandleErrors(PyBool_FromLong(pm->callInstall(PyPackage_ToCpp(pkg), file))); +} + + +static PyObject *PkgManagerConfigure(PyObject *Self,PyObject *Args) +{ + PyPkgManager *pm = GetCpp(Self); + PyObject *pkg; + + if (PyArg_ParseTuple(Args, "O!", &PyPackage_Type,&pkg) == 0) + return 0; + + return HandleErrors(PyBool_FromLong(pm->callConfigure(PyPackage_ToCpp(pkg)))); +} + +static PyObject *PkgManagerRemove(PyObject *Self,PyObject *Args) +{ + PyPkgManager *pm = GetCpp(Self); + PyObject *pkg; + char purge; + + if (PyArg_ParseTuple(Args, "O!b", &PyPackage_Type,&pkg, &purge) == 0) + return 0; + + return HandleErrors(PyBool_FromLong(pm->callRemove(PyPackage_ToCpp(pkg), purge))); +} + +static PyObject *PkgManagerGo(PyObject *Self,PyObject *Args) +{ + PyPkgManager *pm = GetCpp(Self); + int fd; + + if (PyArg_ParseTuple(Args, "i", &fd) == 0) + return 0; + + return HandleErrors(PyBool_FromLong(pm->callGo(fd))); +} + +static PyObject *PkgManagerReset(PyObject *Self,PyObject *Args) +{ + PyPkgManager *pm = GetCpp(Self); + + pm->callReset(); + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyMethodDef PkgManager2Methods[] = +{ + {"install",PkgManagerInstall,METH_VARARGS, + "install(pkg: Package, filename: str) -> bool \n\n" + "Add a install action. Can be overridden in subclasses.\n\n" + "New in version 0.8.0."}, + {"configure",PkgManagerConfigure,METH_VARARGS, + "configure(pkg: Package) -> bool \n\n" + "Add a configure action. Can be overridden in subclasses.\n\n" + "New in version 0.8.0."}, + {"remove",PkgManagerRemove,METH_VARARGS, + "remove(pkg: Package, purge: bool) -> bool \n\n" + "Add a removal action. Can be overridden in subclasses.\n\n" + "New in version 0.8.0."}, + {"go",PkgManagerGo,METH_VARARGS, + "go(status_fd: int) -> bool \n\n" + "Start dpkg. Can be overridden in subclasses.\n\n" + "New in version 0.8.0."}, + {"reset",PkgManagerReset,METH_VARARGS, + "reset()\n\n" + "Reset the package manager for a new round.\n" + "Can be overridden in subclasses.\n\n" + "New in version 0.8.0."}, + {} +}; + +static const char *packagemanager2_doc = + "PackageManager(depcache: apt_pkg.DepCache)\n\n" + "PackageManager objects allow the fetching of packages marked for\n" + "installation and the installation of those packages. The parameter\n" + "'depcache' specifies an apt_pkg.DepCache object where information\n" + "about the package selections is retrieved from.\n\n" + "Methods in this class can be overridden in sub classes\n" + "to implement behavior different from APT's dpkg implementation."; +PyTypeObject PyPackageManager2_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.PackageManager", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE), + packagemanager2_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgManager2Methods, // tp_methods + 0, // tp_members + 0, // tp_getset + &PyPackageManager_Type, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PkgManagerNew, // tp_new +}; + + + /*}}}*/ diff --git a/python/pkgrecords.cc b/python/pkgrecords.cc new file mode 100644 index 0000000..13c2b9a --- /dev/null +++ b/python/pkgrecords.cc @@ -0,0 +1,280 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgrecords.cc,v 1.3 2002/02/26 01:36:15 mdz Exp $ +/* ###################################################################### + + Package Records - Wrapper for the package records functions + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "generic.h" +#include "apt_pkgmodule.h" +#include "pkgrecords.h" + + +#include + /*}}}*/ + + +// PkgRecords Class /*{{{*/ +// --------------------------------------------------------------------- + + +static PyObject *PkgRecordsLookup(PyObject *Self,PyObject *Args) +{ + PkgRecordsStruct &Struct = GetCpp(Self); + + PyObject *PkgFObj; + long int Index; + if (PyArg_ParseTuple(Args,"(O!l)",&PyPackageFile_Type,&PkgFObj,&Index) == 0) + return 0; + + // Get the index and check to make sure it is reasonable + pkgCache::PkgFileIterator &PkgF = GetCpp(PkgFObj); + pkgCache *Cache = PkgF.Cache(); + if (Cache->DataEnd() <= Cache->VerFileP + Index + 1 || + Cache->VerFileP[Index].File != PkgF.MapPointer()) + { + PyErr_SetNone(PyExc_IndexError); + return 0; + } + + // Do the lookup + Struct.Last = &Struct.Records.Lookup(pkgCache::VerFileIterator(*Cache,Cache->VerFileP+Index)); + + // always return true (to make it consistent with the pkgsrcrecords object + return PyBool_FromLong(1); +} + +static PyMethodDef PkgRecordsMethods[] = +{ + {"lookup",PkgRecordsLookup,METH_VARARGS, + "lookup((packagefile: apt_pkg.PackageFile, index: int)) -> bool\n\n" + "Changes to a new package"}, + {} +}; + +/** + * Get the PkgSrcRecordsStruct from a PyObject. If no package has been looked + * up, set an AttributeError using the given name. + */ +static inline PkgRecordsStruct &GetStruct(PyObject *Self,char *name) { + PkgRecordsStruct &Struct = GetCpp(Self); + if (Struct.Last == 0) + PyErr_SetString(PyExc_AttributeError,name); + return Struct; +} + +static PyObject *PkgRecordsGetFileName(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"FileName"); + return (Struct.Last != 0) ? CppPyPath(Struct.Last->FileName()) : 0; +} +static PyObject *PkgRecordsGetHashes(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"Hashes"); + if (Struct.Last == 0) + return 0; + + auto py = CppPyObject_NEW (nullptr, &PyHashStringList_Type); + py->Object = Struct.Last->Hashes(); + return py; +} +static PyObject *PkgRecordsGetMD5Hash(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"MD5Hash"); + if (Struct.Last == NULL) + return 0; + auto hashes = Struct.Last->Hashes(); + auto hash = hashes.find("md5sum"); + if (hash == NULL) + return 0; + return CppPyString(hash->HashValue()); +} +static PyObject *PkgRecordsGetSHA1Hash(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"SHA1Hash"); + if (Struct.Last == NULL) + return 0; + auto hashes = Struct.Last->Hashes(); + auto hash = hashes.find("sha1"); + if (hash == NULL) + return 0; + return CppPyString(hash->HashValue()); +} +static PyObject *PkgRecordsGetSHA256Hash(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"SHA256Hash"); + if (Struct.Last == NULL) + return 0; + auto hashes = Struct.Last->Hashes(); + auto hash = hashes.find("sha256"); + if (hash == NULL) + return 0; + return CppPyString(hash->HashValue()); +} +static PyObject *PkgRecordsGetSourcePkg(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"SourcePkg"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->SourcePkg()) : 0; +} +static PyObject *PkgRecordsGetSourceVer(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"SourceVer"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->SourceVer()) : 0; +} +static PyObject *PkgRecordsGetMaintainer(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"Maintainer"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Maintainer()) : 0; +} +static PyObject *PkgRecordsGetShortDesc(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"ShortDesc"); + return (Struct.Last != 0) ? CppPyLocaleString(Struct.Last->ShortDesc()) : 0; +} +static PyObject *PkgRecordsGetLongDesc(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"LongDesc"); + return (Struct.Last != 0) ? CppPyLocaleString(Struct.Last->LongDesc()) : 0; +} +static PyObject *PkgRecordsGetName(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"Name"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Name()) : 0; +} +static PyObject *PkgRecordsGetHomepage(PyObject *Self,void*) { + PkgRecordsStruct &Struct = GetStruct(Self,"Homepage"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Homepage()) : 0; +} +static PyObject *PkgRecordsGetRecord(PyObject *Self,void*) { + const char *start, *stop; + PkgRecordsStruct &Struct = GetStruct(Self,"Record"); + if (Struct.Last == 0) + return 0; + Struct.Last->GetRec(start, stop); + return PyString_FromStringAndSize(start,stop-start); +} +static PyGetSetDef PkgRecordsGetSet[] = { + {"filename",PkgRecordsGetFileName,0, + "The filename of the package, as stored in the 'Filename' field."}, + {"homepage",PkgRecordsGetHomepage,0, + "The homepage of the package, as stored in the 'Homepage' field."}, + {"long_desc",PkgRecordsGetLongDesc,0, + "The long description of the packages; i.e. all lines in the\n" + "'Description' field except for the first one."}, + {"hashes",PkgRecordsGetHashes,0, + "The hashes of the packages, as a HashStringList"}, + {"md5_hash",PkgRecordsGetMD5Hash,0, + "The MD5 hash value of the package, as stored in the 'MD5Sum' field."}, + {"maintainer",PkgRecordsGetMaintainer,0, + "The maintainer of the package, as stored in the 'Maintainer' field."}, + {"name",PkgRecordsGetName,0, + "The name of the package, as stored in the 'Package' field."}, + {"record",PkgRecordsGetRecord,0, + "The raw record, suitable for parsing by apt_pkg.TagSection."}, + {"sha1_hash",PkgRecordsGetSHA1Hash,0, + "The SHA1 hash value, as stored in the 'SHA1' field."}, + {"sha256_hash",PkgRecordsGetSHA256Hash,0, + "The SHA256 hash value, as stored in the 'SHA256' field."}, + {"short_desc",PkgRecordsGetShortDesc,0, + "The short description of the package, i.e. the first line of the\n" + "'Description' field."}, + {"source_pkg",PkgRecordsGetSourcePkg,0, + "The name of the source package, if different from the name of the\n" + "binary package. This information is retrieved from the 'Source' field."}, + {"source_ver",PkgRecordsGetSourceVer,0, + "The version of the source package, if it differs from the version\n" + "of the binary package. Just like 'source_pkg', this information\n" + "is retrieved from the 'Source' field."}, + {} +}; + +static int PkgRecordsContains(PyObject *Self,PyObject *Arg) +{ + PkgRecordsStruct &Struct = GetStruct(Self,"__contains__"); + if (Struct.Last == nullptr) + return -1; + const char *Name = PyObject_AsString(Arg); + + if (Name == nullptr) + return -1; + + return !Struct.Last->RecordField(Name).empty(); +} + +static PyObject *PkgRecordsMap(PyObject *Self,PyObject *Arg) +{ + PkgRecordsStruct &Struct = GetStruct(Self,"__contains__"); + if (Struct.Last == nullptr) + return nullptr; + + const char *Name = PyObject_AsString(Arg); + if (Name == nullptr) + return nullptr; + + return CppPyString(Struct.Last->RecordField(Name)); +} + + + +PySequenceMethods PkgRecordsSeqMeth = {0,0,0,0,0,0,0,PkgRecordsContains,0,0}; +PyMappingMethods PkgRecordsMapMeth = {0,PkgRecordsMap,0}; + +static PyObject *PkgRecordsNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) +{ + PyObject *Owner; + char *kwlist[] = {"cache",0}; + if (PyArg_ParseTupleAndKeywords(Args,kwds,"O!",kwlist,&PyCache_Type, + &Owner) == 0) + return 0; + + return HandleErrors(CppPyObject_NEW(Owner,type, + GetCpp(Owner))); +} + +static const char *packagerecords_doc = + "PackageRecords(cache: apt_pkg.Cache)\n\n" + "Package Records contain information about packages. Those objects\n" + "can be used to retrieve information such as maintainer or filename\n" + "of a package. They can also be used to retrieve the raw records\n" + "of the packages (i.e. those stanzas stored in Packages files)."; + +PyTypeObject PyPackageRecords_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.PackageRecords", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &PkgRecordsSeqMeth, // tp_as_sequence + &PkgRecordsMapMeth, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC), + packagerecords_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgRecordsMethods, // tp_methods + 0, // tp_members + PkgRecordsGetSet, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PkgRecordsNew, // tp_new +}; + + /*}}}*/ + + diff --git a/python/pkgrecords.h b/python/pkgrecords.h new file mode 100644 index 0000000..1e26c8c --- /dev/null +++ b/python/pkgrecords.h @@ -0,0 +1,10 @@ +#include + +struct PkgRecordsStruct +{ + pkgRecords Records; + pkgRecords::Parser *Last; + + PkgRecordsStruct(pkgCache *Cache) : Records(*Cache), Last(0) {}; + PkgRecordsStruct() : Records(*(pkgCache *)0) {abort();}; // G++ Bug.. +}; diff --git a/python/pkgsrcrecords.cc b/python/pkgsrcrecords.cc new file mode 100644 index 0000000..e813c6e --- /dev/null +++ b/python/pkgsrcrecords.cc @@ -0,0 +1,438 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgsrcrecords.cc,v 1.2 2003/12/26 17:04:22 mdz Exp $ +/* ###################################################################### + + Package Records - Wrapper for the package records functions + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "generic.h" +#include "apt_pkgmodule.h" + +#include + +#include + /*}}}*/ + +// PkgSrcRecordFiles Class /*{{{*/ +// --------------------------------------------------------------------- +typedef pkgSrcRecords::File PkgSrcRecordFilesStruct; + +// compat with the old API that provided a tuple (md5,size,path,type) +static Py_ssize_t pkgSrcRecordFiles_length(PyObject *Self) { + return 4; +} + +// compat with the old API that provided a tuple (md5,size,path,type) +static PyObject* pkgSrcRecordFiles_item(PyObject *Self, Py_ssize_t i) { + APT_IGNORE_DEPRECATED_PUSH + PkgSrcRecordFilesStruct f = GetCpp(Self); + switch (i) { + case 0: + Py_INCREF(Py_None); + return Py_None; + case 1: + return Py_BuildValue("N", MkPyNumber(f.FileSize)); + case 2: + return Py_BuildValue("s", f.Path.c_str()); + case 3: + return Py_BuildValue("s", f.Type.c_str()); + } + + PyErr_Format(PyExc_IndexError, "index %d out of range, consider using the properties instead", i); + return NULL; + APT_IGNORE_DEPRECATED_POP +} + +static PySequenceMethods pkgsrcrecordfiles_as_sequence = { + pkgSrcRecordFiles_length,0,0,pkgSrcRecordFiles_item,0,0,0,0,0,0 +}; + +static PyObject *PkgSrcRecordFilesNew(PyTypeObject *type,PyObject *args,PyObject *kwds) { + char *kwlist[] = {0}; + if (PyArg_ParseTupleAndKeywords(args,kwds,"",kwlist) == 0) + return 0; + + return HandleErrors(CppPyObject_NEW(NULL, type)); +} + +static const char *sourcerecordfile_doc = + "SourceRecordFile()\n\n" + "Provide an easy way to look up the src records of a source package.\n"; + +static PyObject *PkgSrcRecordFilesGetPath(PyObject *Self,void*) { + PkgSrcRecordFilesStruct f = GetCpp(Self); + return CppPyString(f.Path.c_str()); +} + +static PyObject *PkgSrcRecordFilesGetType(PyObject *Self,void*) { + PkgSrcRecordFilesStruct f = GetCpp(Self); + return CppPyString(f.Type.c_str()); +} + +static PyObject *PkgSrcRecordFilesGetSize(PyObject *Self,void*) { + PkgSrcRecordFilesStruct f = GetCpp(Self); + return Py_BuildValue("N", MkPyNumber(f.FileSize)); +} + +static PyObject *PkgSrcRecordFilesGetHashes(PyObject *Self,void*) { + PkgSrcRecordFilesStruct f = GetCpp(Self); + auto py = CppPyObject_NEW (nullptr, &PyHashStringList_Type); + py->Object = f.Hashes; + return py; +} + +static PyGetSetDef PkgSrcRecordFilesGetSet[] = { + {"path",PkgSrcRecordFilesGetPath,0, + "The remote path of the source package file."}, + {"type",PkgSrcRecordFilesGetType,0, + "The type of the source package file."}, + {"size",PkgSrcRecordFilesGetSize,0, + "The size of the source package file."}, + {"hashes",PkgSrcRecordFilesGetHashes,0, + "The hashes of the source package file."}, + {} +}; + +PyTypeObject PySourceRecordFiles_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.SourceRecordFiles", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &pkgsrcrecordfiles_as_sequence, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE), + sourcerecordfile_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + PkgSrcRecordFilesGetSet, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PkgSrcRecordFilesNew, // tp_new +}; +// --------------------------------------------------------------------- + +struct PkgSrcRecordsStruct +{ + pkgSourceList List; + pkgSrcRecords *Records; + pkgSrcRecords::Parser *Last; + + PkgSrcRecordsStruct() : Last(0) { + List.ReadMainList(); + Records = new pkgSrcRecords(List); + }; + ~PkgSrcRecordsStruct() { + delete Records; + }; +}; + + +// PkgSrcRecords Class /*{{{*/ +// --------------------------------------------------------------------- + +static char *doc_PkgSrcRecordsLookup = + "lookup(name: str) -> bool\n\n" + "Look up the source package with the given name. Each call moves\n" + "the position of the records parser forward. If there are no\n" + "more records, return None. If the lookup failed this way,\n" + "access to any of the attributes will result in an AttributeError."; +static PyObject *PkgSrcRecordsLookup(PyObject *Self,PyObject *Args) +{ + PkgSrcRecordsStruct &Struct = GetCpp(Self); + + char *Name = 0; + if (PyArg_ParseTuple(Args,"s",&Name) == 0) + return 0; + + Struct.Last = Struct.Records->Find(Name, false); + if (Struct.Last == 0) { + Struct.Records->Restart(); + Py_INCREF(Py_None); + return HandleErrors(Py_None); + } + + return PyBool_FromLong(1); +} + +static char *doc_PkgSrcRecordsRestart = + "restart()\n\n" + "Restart the lookup process. This moves the parser to the first\n" + "package and lookups can now be made just like on a new object."; +static PyObject *PkgSrcRecordsRestart(PyObject *Self,PyObject *Args) +{ + PkgSrcRecordsStruct &Struct = GetCpp(Self); + + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + Struct.Records->Restart(); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static char *doc_PkgSrcRecordsStep = + "step() -> bool\n\n" + "Go to the source package. Each call moves\n" + "the position of the records parser forward. If there are no\n" + "more records, return None. If the lookup failed this way,\n" + "access to any of the attributes will result in an AttributeError."; +static PyObject *PkgSrcRecordsStep(PyObject *Self,PyObject *Args) +{ + PkgSrcRecordsStruct &Struct = GetCpp(Self); + + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + Struct.Last = (pkgSrcRecords::Parser*)Struct.Records->Step(); + if (Struct.Last == 0) { + Struct.Records->Restart(); + Py_INCREF(Py_None); + return HandleErrors(Py_None); + } + + return PyBool_FromLong(1); +} + +static PyMethodDef PkgSrcRecordsMethods[] = +{ + {"lookup",PkgSrcRecordsLookup,METH_VARARGS,doc_PkgSrcRecordsLookup}, + {"restart",PkgSrcRecordsRestart,METH_VARARGS,doc_PkgSrcRecordsRestart}, + {"step",PkgSrcRecordsStep,METH_VARARGS,doc_PkgSrcRecordsStep}, + {} +}; + +/** + * Get the PkgSrcRecordsStruct from a PyObject. If no package has been looked + * up, set an AttributeError using the given name. + */ +static inline PkgSrcRecordsStruct &GetStruct(PyObject *Self,char *name) { + PkgSrcRecordsStruct &Struct = GetCpp(Self); + if (Struct.Last == 0) + PyErr_SetString(PyExc_AttributeError,name); + return Struct; +} + +static PyObject *PkgSrcRecordsGetPackage(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Package"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Package()) : 0; +} +static PyObject *PkgSrcRecordsGetVersion(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Version"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Version()) : 0; +} +static PyObject *PkgSrcRecordsGetMaintainer(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Maintainer"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Maintainer()) : 0; +} +static PyObject *PkgSrcRecordsGetSection(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Section"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->Section()) : 0; +} +static PyObject *PkgSrcRecordsGetRecord(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Record"); + return (Struct.Last != 0) ? CppPyString(Struct.Last->AsStr()) : 0; +} +static PyObject *PkgSrcRecordsGetBinaries(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Binaries"); + if (Struct.Last == 0) + return 0; + PyObject *List = PyList_New(0); + for(const char **b = Struct.Last->Binaries(); *b != 0; ++b) + PyList_Append(List, CppPyString(*b)); + return List; // todo +} +static PyObject *PkgSrcRecordsGetIndex(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Index"); + if (Struct.Last == 0) + return 0; + const pkgIndexFile &tmp = Struct.Last->Index(); + CppPyObject *PyObj; + PyObj = CppPyObject_NEW(Self,&PyIndexFile_Type, + (pkgIndexFile*)&tmp); + // Do not delete the pkgIndexFile*, it is managed by PkgSrcRecords::Parser. + PyObj->NoDelete=true; + return PyObj; +} + +static PyObject *PkgSrcRecordsGetFiles(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"Files"); + if (Struct.Last == 0) + return 0; + PyObject *List = PyList_New(0); + + std::vector f; + if(!Struct.Last->Files(f)) + return NULL; // error + + PyObject *v; + for(unsigned int i=0;i(Self, &PySourceRecordFiles_Type, f[i]); + PyList_Append(List, v); + Py_DECREF(v); + } + return List; +} + +static PyObject *PkgSrcRecordsGetBuildDepends(PyObject *Self,void*) { + PkgSrcRecordsStruct &Struct = GetStruct(Self,"BuildDepends"); + if (Struct.Last == 0) + return 0; + + PyObject *Dict = PyDict_New(); + PyObject *Dep = 0; + PyObject *LastDep = 0; + PyObject *OrGroup = 0; + + std::vector bd; + if(!Struct.Last->BuildDepends(bd, false /* arch-only*/)) + return NULL; // error + + PyObject *v; + for(unsigned int i=0;i(NULL, type)); +} + +static const char *sourcerecords_doc = + "SourceRecords()\n\n" + "Provide an easy way to look up the records of source packages and\n" + "provide easy attributes for some widely used fields of the record."; + +PyTypeObject PySourceRecords_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.SourceRecords", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE), + sourcerecords_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgSrcRecordsMethods, // tp_methods + 0, // tp_members + PkgSrcRecordsGetSet, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PkgSrcRecordsNew, // tp_new +}; + + + /*}}}*/ + diff --git a/python/policy.cc b/python/policy.cc new file mode 100644 index 0000000..037a530 --- /dev/null +++ b/python/policy.cc @@ -0,0 +1,243 @@ +/* + * policy.cc - Wrapper around pkgPolicy + * + * Copyright 2009 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ +#include +#include "apt_pkgmodule.h" +#include "generic.h" +#include + +static PyObject *policy_new(PyTypeObject *type,PyObject *Args, + PyObject *kwds) { + PyObject *cache; + char *kwlist[] = {"cache", NULL}; + if (PyArg_ParseTupleAndKeywords(Args, kwds, "O", kwlist, &cache) == 0) + return 0; + if (!PyObject_TypeCheck(cache, &PyCache_Type)) { + PyErr_SetString(PyExc_TypeError,"`cache` must be a apt_pkg.Cache()."); + return 0; + } + pkgPolicy *policy = new pkgPolicy(GetCpp(cache)); + return CppPyObject_NEW(cache,&PyPolicy_Type,policy); +} + +static char *policy_get_priority_doc = + "get_priority(package: Union[apt_pkg.Package, apt_pkg.Version, apt_pkg.PackageFile]) -> int\n\n" + "Return the priority of the package."; + +PyObject *policy_get_priority(PyObject *self, PyObject *arg) { + pkgPolicy *policy = GetCpp(self); + if (PyObject_TypeCheck(arg, &PyVersion_Type)) { + auto ver = GetCpp(arg); + return MkPyNumber(policy->GetPriority(ver)); + } else if (PyObject_TypeCheck(arg, &PyPackageFile_Type)) { + pkgCache::PkgFileIterator pkgfile = GetCpp(arg); + return MkPyNumber(policy->GetPriority(pkgfile)); + } else { + PyErr_SetString(PyExc_TypeError,"Argument must be of Version or PackageFile."); + return 0; + } +} + + +static char *policy_set_priority_doc = + "set_priority(which: Union[apt_pkg.Version, apt_pkg.PackageFile], priority: int) -> None\n\n" + "Override priority for the given package/file. Behavior is undefined if" + "a preferences file is read after that, or :meth:`init_defaults` is called."; +static PyObject *policy_set_priority(PyObject *self, PyObject *args) { + PyObject *which; + signed short priority; + if (PyArg_ParseTuple(args, "Oh", &which, &priority) == 0) + return 0; + pkgPolicy *policy = GetCpp(self); + + if (PyObject_TypeCheck(which, &PyVersion_Type)) { + auto ver = GetCpp(which); + policy->SetPriority(ver, priority); + } else if (PyObject_TypeCheck(which, &PyPackageFile_Type)) { + auto pkgfile = GetCpp(which); + policy->SetPriority(pkgfile, priority); + } else { + PyErr_SetString(PyExc_TypeError,"Argument must be of Version or PackageFile."); + return 0; + } + + HandleErrors(); + Py_RETURN_NONE; +} + +static char *policy_get_candidate_ver_doc = + "get_match(package: apt_pkg.Package) -> Optional[apt_pkg.Version]\n\n" + "Get the best package for the job."; + +PyObject *policy_get_candidate_ver(PyObject *self, PyObject *arg) { + if (PyObject_TypeCheck(arg, &PyPackage_Type)) { + pkgPolicy *policy = GetCpp(self); + pkgCache::PkgIterator pkg = GetCpp(arg); + pkgCache::VerIterator ver = policy->GetCandidateVer(pkg); + if (ver.end()) { + HandleErrors(); + Py_RETURN_NONE; + } + return CppPyObject_NEW(arg,&PyVersion_Type, + ver); + } else { + PyErr_SetString(PyExc_TypeError,"Argument must be of Package()."); + return 0; + } +} + +static char *policy_read_pinfile_doc = + "read_pinfile(filename: str) -> bool\n\n" + "Read the pin file given by filename (e.g. '/etc/apt/preferences')\n" + "and add it to the policy."; + +static PyObject *policy_read_pinfile(PyObject *self, PyObject *arg) { + PyApt_Filename name; + if (!name.init(arg)) + return 0; + pkgPolicy *policy = GetCpp(self); + + return PyBool_FromLong(ReadPinFile(*policy, name)); +} + +#if (APT_PKG_MAJOR > 4 || (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 8)) +static char *policy_read_pindir_doc = + "read_pindir(dirname: str) -> bool\n\n" + "Read the pin files in the given dir (e.g. '/etc/apt/preferences.d')\n" + "and add them to the policy."; + +static PyObject *policy_read_pindir(PyObject *self, PyObject *arg) { + PyApt_Filename name; + if (!name.init(arg)) + return 0; + pkgPolicy *policy = GetCpp(self); + + return PyBool_FromLong(ReadPinDir(*policy, name)); +} +#endif + +static char *policy_create_pin_doc = + "create_pin(type: str, pkg: str, data: str, priority: int)\n\n" + "Create a pin for the policy. The parameter 'type' refers to one of the\n" + "strings 'Version', 'Release', or 'Origin'. The argument 'pkg' is the\n" + "name of the package. The parameter 'data' refers to the value\n" + "(e.g. 'unstable' for type='Release') and the other possible options.\n" + "The parameter 'priority' gives the priority of the pin."; + +static PyObject *policy_create_pin(PyObject *self, PyObject *args) { + pkgVersionMatch::MatchType match_type; + const char *type, *pkg, *data; + signed short priority; + if (PyArg_ParseTuple(args, "sssh", &type, &pkg, &data, &priority) == 0) + return 0; + pkgPolicy *policy = GetCpp(self); + if (strcmp(type,"Version") == 0 || strcmp(type, "version") == 0) + match_type = pkgVersionMatch::Version; + else if (strcmp(type,"Release") == 0 || strcmp(type, "release") == 0) + match_type = pkgVersionMatch::Release; + else if (strcmp(type,"Origin") == 0 || strcmp(type, "origin") == 0) + match_type = pkgVersionMatch::Origin; + else + match_type = pkgVersionMatch::None; + policy->CreatePin(match_type,pkg,data,priority); + HandleErrors(); + Py_RETURN_NONE; +} + +static char *policy_init_defaults_doc = + "init_defaults()\n\n" + "Initialize defaults. Needed after calling :meth:`create_pin()`\n" + "with an empty `pkg` argument"; +static PyObject *policy_init_defaults(PyObject *self, PyObject *args) { + if (PyArg_ParseTuple(args, "") == 0) + return 0; + pkgPolicy *policy = GetCpp(self); + policy->InitDefaults(); + HandleErrors(); + Py_RETURN_NONE; +} + +static PyMethodDef policy_methods[] = { + {"get_priority",(PyCFunction)policy_get_priority,METH_O, + policy_get_priority_doc}, + {"set_priority",policy_set_priority,METH_VARARGS,policy_set_priority_doc}, + {"get_candidate_ver",(PyCFunction)policy_get_candidate_ver,METH_O, + policy_get_candidate_ver_doc}, + {"read_pinfile",(PyCFunction)policy_read_pinfile,METH_O, + policy_read_pinfile_doc}, +#if (APT_PKG_MAJOR > 4 || (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 8)) + {"read_pindir",(PyCFunction)policy_read_pindir,METH_O, + policy_read_pindir_doc}, +#endif + {"create_pin",policy_create_pin,METH_VARARGS,policy_create_pin_doc}, + {"init_defaults",policy_init_defaults,METH_VARARGS,policy_init_defaults_doc}, + {} +}; + +static char *policy_doc = + "Policy(cache)\n\n" + "Representation of the policy of the Cache object given by cache. This\n" + "provides a superset of policy-related functionality compared to the\n" + "DepCache class. The DepCache can be used for most purposes, but there\n" + "may be some cases where a special policy class is needed."; + +PyTypeObject PyPolicy_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Policy", // tp_name + sizeof(CppPyObject),// tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC), + policy_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + policy_methods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + policy_new, // tp_new +}; diff --git a/python/progress.cc b/python/progress.cc new file mode 100644 index 0000000..f4ed8e6 --- /dev/null +++ b/python/progress.cc @@ -0,0 +1,473 @@ +// Description /*{{{*/ +// $Id: progress.cc,v 1.5 2003/06/03 03:03:23 mvo Exp $ +/* ###################################################################### + + Progress - Wrapper for the progress related functions + + ##################################################################### */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "progress.h" +#include "generic.h" +#include "apt_pkgmodule.h" + +/** + * Set an attribute on an object, after creating the value with + * Py_BuildValue(fmt, arg). Afterwards, decrease its refcount and return + * whether setting the attribute was successful. + */ +template +inline bool setattr(PyObject *object, const char *attr, const char *fmt, T arg) +{ + if (!object) + return false; + PyObject *value = Py_BuildValue(fmt, arg); + if (value == NULL) + return false; + + int result = PyObject_SetAttrString(object, attr, value); + Py_DECREF(value); + return result != -1; +} + +inline PyObject *TUPLEIZE(PyObject *op) { + PyObject *ret = Py_BuildValue("(O)", op); + Py_DECREF(op); + return ret; +} + +// generic +bool PyCallbackObj::RunSimpleCallback(const char* method_name, + PyObject *arglist, + PyObject **res) +{ + if(callbackInst == 0) { + Py_XDECREF(arglist); + return false; + } + + PyObject *method = PyObject_GetAttrString(callbackInst,(char*) method_name); + if(method == NULL) { + Py_XDECREF(arglist); + if (res) { + Py_INCREF(Py_None); + *res = Py_None; + } + return false; + } + + PyObject *result = PyObject_CallObject(method, arglist); + Py_XDECREF(arglist); + + if(result == NULL) { + // exception happend + std::cerr << "Error in function " << method_name << std::endl; + PyErr_Print(); + PyErr_Clear(); + + return false; + } + if(res != NULL) + *res = result; + else + Py_XDECREF(result); + Py_XDECREF(method); + + return true; +} + + +// OpProgress interface +void PyOpProgress::Update() +{ + // Build up the argument list... + if(!CheckChange(0.7)) + return; + + setattr(callbackInst, "op", "s", Op.c_str()); + setattr(callbackInst, "subop", "s", SubOp.c_str()); + setattr(callbackInst, "major_change", "b", MajorChange); + setattr(callbackInst, "percent", "N", MkPyNumber(Percent)); + RunSimpleCallback("update"); +} + +void PyOpProgress::Done() +{ + RunSimpleCallback("done"); +} + + + +// fetcher interface + + + +// apt interface + +PyObject *PyFetchProgress::GetDesc(pkgAcquire::ItemDesc *item) { + if (!pyAcquire && item->Owner && item->Owner->GetOwner()) { + pyAcquire = PyAcquire_FromCpp(item->Owner->GetOwner(), false, NULL); + } + PyObject *pyItem = PyAcquireItem_FromCpp(item->Owner, false, pyAcquire); + PyObject *pyDesc = PyAcquireItemDesc_FromCpp(item, false, pyItem); + Py_DECREF(pyItem); + return pyDesc; +} + +bool PyFetchProgress::MediaChange(std::string Media, std::string Drive) +{ + PyCbObj_END_ALLOW_THREADS + PyObject *arglist = Py_BuildValue("(ss)", Media.c_str(), Drive.c_str()); + PyObject *result = NULL; + + if(PyObject_HasAttrString(callbackInst, "mediaChange")) + RunSimpleCallback("mediaChange", arglist, &result); + else + RunSimpleCallback("media_change", arglist, &result); + + bool res = true; + if(!PyArg_Parse(result, "b", &res)) { + // no return value or None, assume false + PyCbObj_BEGIN_ALLOW_THREADS + return false; + } + + PyCbObj_BEGIN_ALLOW_THREADS + return res; +} + +void PyFetchProgress::UpdateStatus(pkgAcquire::ItemDesc &Itm, int status) +{ + // Added object file size and object partial size to + // parameters that are passed to updateStatus. + // -- Stephan + PyObject *arglist = Py_BuildValue("(sssNNN)", Itm.URI.c_str(), + Itm.Description.c_str(), + Itm.ShortDesc.c_str(), + MkPyNumber(status), + MkPyNumber(Itm.Owner->FileSize), + MkPyNumber(Itm.Owner->PartialSize)); + + RunSimpleCallback("update_status_full", arglist); + + // legacy version of the interface + + arglist = Py_BuildValue("(sssN)", Itm.URI.c_str(), Itm.Description.c_str(), + Itm.ShortDesc.c_str(), MkPyNumber(status)); + + if(PyObject_HasAttrString(callbackInst, "updateStatus")) + RunSimpleCallback("updateStatus", arglist); + else + RunSimpleCallback("update_status", arglist); +} + +void PyFetchProgress::IMSHit(pkgAcquire::ItemDesc &Itm) +{ + PyCbObj_END_ALLOW_THREADS + if (PyObject_HasAttrString(callbackInst, "ims_hit")) + RunSimpleCallback("ims_hit", TUPLEIZE(GetDesc(&Itm))); + else + UpdateStatus(Itm, DLHit); + PyCbObj_BEGIN_ALLOW_THREADS +} + +void PyFetchProgress::Fetch(pkgAcquire::ItemDesc &Itm) +{ + PyCbObj_END_ALLOW_THREADS + if (PyObject_HasAttrString(callbackInst, "fetch")) + RunSimpleCallback("fetch", TUPLEIZE(GetDesc(&Itm))); + else + UpdateStatus(Itm, DLQueued); + PyCbObj_BEGIN_ALLOW_THREADS +} + +void PyFetchProgress::Done(pkgAcquire::ItemDesc &Itm) +{ + PyCbObj_END_ALLOW_THREADS + if (PyObject_HasAttrString(callbackInst, "done")) + RunSimpleCallback("done", TUPLEIZE(GetDesc(&Itm))); + else + UpdateStatus(Itm, DLDone); + PyCbObj_BEGIN_ALLOW_THREADS +} + +void PyFetchProgress::Fail(pkgAcquire::ItemDesc &Itm) +{ + PyCbObj_END_ALLOW_THREADS + if (PyObject_HasAttrString(callbackInst, "fail")) { + RunSimpleCallback("fail", TUPLEIZE(GetDesc(&Itm))); + PyCbObj_BEGIN_ALLOW_THREADS + return; + } + + // Ignore certain kinds of transient failures (bad code) + if (Itm.Owner->Status == pkgAcquire::Item::StatIdle) { + PyCbObj_BEGIN_ALLOW_THREADS + return; + } + + if (Itm.Owner->Status == pkgAcquire::Item::StatDone) + { + UpdateStatus(Itm, DLIgnored); + } + + + if (PyObject_HasAttrString(callbackInst, "fail")) + RunSimpleCallback("fail", TUPLEIZE(GetDesc(&Itm))); + else + UpdateStatus(Itm, DLFailed); + PyCbObj_BEGIN_ALLOW_THREADS +} + +void PyFetchProgress::Start() +{ + pkgAcquireStatus::Start(); + + + RunSimpleCallback("start"); + /* After calling the start method we can safely allow + * other Python threads to do their work for now. + */ + PyCbObj_BEGIN_ALLOW_THREADS +} + + +void PyFetchProgress::Stop() +{ + /* After the stop operation occurred no other threads + * are allowed. This is done so we have a matching + * PyCbObj_END_ALLOW_THREADS to our previous + * PyCbObj_BEGIN_ALLOW_THREADS (Python requires this!). + */ + + PyCbObj_END_ALLOW_THREADS + pkgAcquireStatus::Stop(); + RunSimpleCallback("stop"); +} + +bool PyFetchProgress::Pulse(pkgAcquire * Owner) +{ + PyCbObj_END_ALLOW_THREADS + pkgAcquireStatus::Pulse(Owner); + + if(callbackInst == 0) { + PyCbObj_BEGIN_ALLOW_THREADS + return false; + } + + setattr(callbackInst, "last_bytes", "N", MkPyNumber(LastBytes)); + setattr(callbackInst, "current_cps", "N", MkPyNumber(CurrentCPS)); + setattr(callbackInst, "current_bytes", "N", MkPyNumber(CurrentBytes)); + setattr(callbackInst, "total_bytes", "N", MkPyNumber(TotalBytes)); + setattr(callbackInst, "fetched_bytes", "N", MkPyNumber(FetchedBytes)); + setattr(callbackInst, "elapsed_time", "N", MkPyNumber(ElapsedTime)); + setattr(callbackInst, "current_items", "N", MkPyNumber(CurrentItems)); + setattr(callbackInst, "total_items", "N", MkPyNumber(TotalItems)); + + // New style + if (!PyObject_HasAttrString(callbackInst, "updateStatus")) { + PyObject *result1; + bool res1 = true; + + if (pyAcquire == NULL) { + pyAcquire = PyAcquire_FromCpp(Owner, false, NULL); + } + Py_INCREF(pyAcquire); + + if (RunSimpleCallback("pulse", TUPLEIZE(pyAcquire) , &result1)) { + if (result1 != NULL && + result1 != Py_None && + PyArg_Parse(result1, "b", &res1) && + res1 == false) { + // the user returned a explicit false here, stop + PyCbObj_BEGIN_ALLOW_THREADS + return false; + } + } + PyCbObj_BEGIN_ALLOW_THREADS + return true; + } + return false; +} + + + +// install progress + +void PyInstallProgress::StartUpdate() +{ + RunSimpleCallback("start_update"); + PyCbObj_BEGIN_ALLOW_THREADS +} + +void PyInstallProgress::UpdateInterface() +{ + PyCbObj_END_ALLOW_THREADS + RunSimpleCallback("update_interface"); + PyCbObj_BEGIN_ALLOW_THREADS +} + +void PyInstallProgress::FinishUpdate() +{ + PyCbObj_END_ALLOW_THREADS + RunSimpleCallback("finish_update"); +} + +pkgPackageManager::OrderResult PyInstallProgress::Run(pkgPackageManager *pm) +{ + pkgPackageManager::OrderResult res; + int ret; + pid_t child_id; + +#if 0 // FIXME: this needs to be merged into apt to support medium swaping + res = pm->DoInstallPreFork(); + if (res == pkgPackageManager::Failed) + return res; +#endif + + // support custom fork methods + if(PyObject_HasAttrString(callbackInst, "fork")) { + PyObject *method = PyObject_GetAttrString(callbackInst, "fork"); + PyObject *arglist = Py_BuildValue("()"); + PyObject *result = PyObject_CallObject(method, arglist); + Py_DECREF(arglist); + if (result == NULL) { + std::cerr << "fork method invalid" << std::endl; + PyErr_Print(); + return pkgPackageManager::Failed; + } + if(!PyArg_Parse(result, "i", &child_id) ) { + std::cerr << "custom fork() result could not be parsed?"<< std::endl; + return pkgPackageManager::Failed; + } + } else { + child_id = fork(); + } + + PyObject *child_o = MkPyNumber(child_id); + PyObject_SetAttrString(callbackInst, "child_pid", child_o); + Py_DECREF(child_o); + +#if 0 // FIXME: this needs to be merged into apt to support medium swaping + if (child_id == 0) { + res = pm->DoInstallPostFork(); + _exit(res); + } +#endif + if (child_id == 0) { + PyObject *v = PyObject_GetAttrString(callbackInst, "writefd"); + if(v) { + int fd = PyObject_AsFileDescriptor(v); + + APT::Progress::PackageManagerProgressFd progress(fd); + res = pm->DoInstall(&progress); + } else { + APT::Progress::PackageManagerProgressFd progress(-1); + res = pm->DoInstall(&progress); + } + _exit(res); + } + + StartUpdate(); + + + PyCbObj_END_ALLOW_THREADS + if(PyObject_HasAttrString(callbackInst, "waitChild") || + PyObject_HasAttrString(callbackInst, "wait_child")) { + PyObject *method; + if (PyObject_HasAttrString(callbackInst, "waitChild")) + method = PyObject_GetAttrString(callbackInst, "waitChild"); + else + method = PyObject_GetAttrString(callbackInst, "wait_child"); + PyObject *result = PyObject_CallObject(method, NULL); + if (result == NULL) { + std::cerr << "waitChild method invalid" << std::endl; + PyErr_Print(); + PyCbObj_BEGIN_ALLOW_THREADS + return pkgPackageManager::Failed; + } + if(!PyArg_Parse(result, "i", &res) ) { + std::cerr << "custom waitChild() result could not be parsed?"<< std::endl; + PyCbObj_BEGIN_ALLOW_THREADS + return pkgPackageManager::Failed; + } + PyCbObj_BEGIN_ALLOW_THREADS + } else { + PyCbObj_BEGIN_ALLOW_THREADS + while (waitpid(child_id, &ret, WNOHANG) == 0) { + PyCbObj_END_ALLOW_THREADS + UpdateInterface(); + PyCbObj_BEGIN_ALLOW_THREADS + } + + res = (pkgPackageManager::OrderResult) WEXITSTATUS(ret); + } + + FinishUpdate(); + + return res; +} + + +//----------------------------------------------------------------------------- +// apt-cdrom interface + +void PyCdromProgress::Update(std::string text, int current) +{ + PyObject *arglist = Py_BuildValue("(si)", text.c_str(), current); + setattr(callbackInst, "total_steps", "i", totalSteps); + RunSimpleCallback("update", arglist); +} + +bool PyCdromProgress::ChangeCdrom() +{ + PyObject *arglist = Py_BuildValue("()"); + PyObject *result = NULL; + if (PyObject_HasAttrString(callbackInst, "changeCdrom")) + RunSimpleCallback("changeCdrom", arglist, &result); + else + RunSimpleCallback("change_cdrom", arglist, &result); + + bool res = true; + if(!PyArg_Parse(result, "b", &res)) + std::cerr << "ChangeCdrom: result could not be parsed" << std::endl; + + return res; +} + + +bool PyCdromProgress::AskCdromName(std::string &Name) +{ + PyObject *arglist = Py_BuildValue("()"); + const char *new_name; + bool res; + PyObject *result = NULL; + + // Old style: (True, name) on success, (False, name) on failure. + if (PyObject_HasAttrString(callbackInst, "askAdromName")) { + RunSimpleCallback("askAdromName", arglist, &result); + if(!PyArg_Parse(result, "(bs)", &res, &new_name)) + std::cerr << "AskCdromName: result could not be parsed" << std::endl; + // set the new name + Name =std:: string(new_name); + return res; + } + // New style: String on success, None on failure. + else { + RunSimpleCallback("ask_cdrom_name", arglist, &result); + if(result == Py_None) + return false; + if(!PyArg_Parse(result, "s", &new_name)) + std::cerr << "ask_cdrom_name: result could not be parsed" << std::endl; + else + Name = std::string(new_name); + return true; + } +} diff --git a/python/progress.h b/python/progress.h new file mode 100644 index 0000000..b46ac98 --- /dev/null +++ b/python/progress.h @@ -0,0 +1,120 @@ +// Description /*{{{*/ +// $Id: progress.h,v 1.5 2003/06/03 03:03:23 mdz Exp $ +/* ###################################################################### + + Progress - Wrapper for the progress related functions + + ##################################################################### */ + +#ifndef PROGRESS_H +#define PROGRESS_H + +#include +#include +#include +#include +#include + +/* PyCbObj_BEGIN_ALLOW_THREADS and PyCbObj_END_ALLOW_THREADS are sligthly + * modified versions of Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS. + * Instead of storing the thread state in a function-local variable these + * use a class attribute (with the same) name, allowing blocking and + * unblocking from different class methods. + * Py_BLOCK_THREADS and Py_UNBLOCK_THREADS do not define their own + * local variable but use the one provided by PyCbObj_BEGIN_ALLOW_THREADS + * and thus are the same as Py_BLOCK_THREADS and Py_UNBLOCK_THREADS. + */ +#define PyCbObj_BEGIN_ALLOW_THREADS \ + _save = PyEval_SaveThread(); +#define PyCbObj_END_ALLOW_THREADS \ + PyEval_RestoreThread(_save); \ + _save = NULL; +#define PyCbObj_BLOCK_THREADS Py_BLOCK_THREADS +#define PyCbObj_UNBLOCK_THREADS Py_UNBLOCK_THREADS + +class PyCallbackObj { + protected: + PyObject *callbackInst; + PyThreadState *_save; + + public: + void setCallbackInst(PyObject *o) { + Py_INCREF(o); + callbackInst = o; + } + + bool RunSimpleCallback(const char *method, PyObject *arglist=NULL, + PyObject **result=NULL); + + PyCallbackObj() : callbackInst(0), _save(0) {}; + ~PyCallbackObj() {Py_DECREF(callbackInst); }; +}; + +struct PyOpProgress : public OpProgress, public PyCallbackObj +{ + + virtual void Update(); + virtual void Done(); + + PyOpProgress() : OpProgress(), PyCallbackObj() {}; +}; + + +struct PyFetchProgress : public pkgAcquireStatus, public PyCallbackObj +{ + protected: + PyObject *pyAcquire; + PyObject *GetDesc(pkgAcquire::ItemDesc *item); + public: + enum { + DLDone, DLQueued, DLFailed, DLHit, DLIgnored + }; + + void UpdateStatus(pkgAcquire::ItemDesc & Itm, int status); + + virtual bool MediaChange(std::string Media, std::string Drive); + + void setPyAcquire(PyObject *o) { + Py_CLEAR(pyAcquire); + Py_INCREF(o); + pyAcquire = o; + } + + /* apt stuff */ + virtual void IMSHit(pkgAcquire::ItemDesc &Itm); + virtual void Fetch(pkgAcquire::ItemDesc &Itm); + virtual void Done(pkgAcquire::ItemDesc &Itm); + virtual void Fail(pkgAcquire::ItemDesc &Itm); + virtual void Start(); + virtual void Stop(); + + bool Pulse(pkgAcquire * Owner); + PyFetchProgress() : PyCallbackObj(), pyAcquire(0) {}; + ~PyFetchProgress() { Py_XDECREF(pyAcquire); }; +}; + +struct PyInstallProgress : public PyCallbackObj +{ + void StartUpdate(); + void UpdateInterface(); + void FinishUpdate(); + + pkgPackageManager::OrderResult Run(pkgPackageManager *pm); + + PyInstallProgress() : PyCallbackObj() {}; +}; + +struct PyCdromProgress : public pkgCdromStatus, public PyCallbackObj +{ + // update steps, will be called regularly as a "pulse" + virtual void Update(std::string text="", int current=0); + // ask for cdrom insert + virtual bool ChangeCdrom(); + // ask for cdrom name + virtual bool AskCdromName(std::string &Name); + + PyCdromProgress() : PyCallbackObj() {}; +}; + + +#endif diff --git a/python/python-apt-helpers.cc b/python/python-apt-helpers.cc new file mode 100644 index 0000000..bc58d93 --- /dev/null +++ b/python/python-apt-helpers.cc @@ -0,0 +1,69 @@ +/* + * python-apt.h - Common object creation functions for the public API + * + * Copyright 2010 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "apt_pkgmodule.h" + +/** + * Short macro to be used for the generic FromCpp functions. + * + */ +#define NEW_FROM(NAME,TYPE,Cpp) \ +PyObject* NAME(Cpp const &obj, bool Delete, PyObject *Owner) \ +{ \ + CppPyObject *Obj = CppPyObject_NEW(Owner, TYPE, obj); \ + Obj->NoDelete = (!Delete); \ + return Obj; \ +} + +// Create all those functions +NEW_FROM(PyAcquireFile_FromCpp,&PyAcquireFile_Type,pkgAcqFile*) +NEW_FROM(PyAcquireItem_FromCpp,&PyAcquireItem_Type,pkgAcquire::Item*) +NEW_FROM(PyAcquireItemDesc_FromCpp,&PyAcquireItemDesc_Type,pkgAcquire::ItemDesc*) +NEW_FROM(PyAcquireWorker_FromCpp,&PyAcquireWorker_Type,pkgAcquire::Worker*) +NEW_FROM(PyActionGroup_FromCpp,&PyActionGroup_Type,pkgDepCache::ActionGroup*) +NEW_FROM(PyCache_FromCpp,&PyCache_Type,pkgCache*) +NEW_FROM(PyCacheFile_FromCpp,&PyCacheFile_Type,pkgCacheFile*) +NEW_FROM(PyCdrom_FromCpp,&PyCdrom_Type,pkgCdrom) +NEW_FROM(PyConfiguration_FromCpp,&PyConfiguration_Type,Configuration*) +NEW_FROM(PyDepCache_FromCpp,&PyDepCache_Type,pkgDepCache*) +NEW_FROM(PyDependency_FromCpp,&PyDependency_Type,pkgCache::DepIterator) +//NEW_FROM(PyDependencyList_FromCpp,&PyDependencyList_Type,RDepListStruct) +NEW_FROM(PyDescription_FromCpp,&PyDescription_Type,pkgCache::DescIterator) +NEW_FROM(PyHashes_FromCpp,&PyHashes_Type,Hashes) +NEW_FROM(PyHashString_FromCpp,&PyHashString_Type,HashString*) +NEW_FROM(PyMetaIndex_FromCpp,&PyMetaIndex_Type,metaIndex*) +NEW_FROM(PyPackage_FromCpp,&PyPackage_Type,pkgCache::PkgIterator) +NEW_FROM(PyGroup_FromCpp,&PyGroup_Type,pkgCache::GrpIterator) +NEW_FROM(PyIndexFile_FromCpp,&PyIndexFile_Type,pkgIndexFile*) +NEW_FROM(PyOrderList_FromCpp,&PyOrderList_Type,pkgOrderList*) +NEW_FROM(PyPackageFile_FromCpp,&PyPackageFile_Type,pkgCache::PkgFileIterator) +//NEW_FROM(PyPackageList_FromCpp,&PyPackageList_Type,PkgListStruct) +NEW_FROM(PyPackageManager_FromCpp,&PyPackageManager_Type,pkgPackageManager*) +//NEW_FROM(PyPackageRecords_FromCpp,&PyPackageRecords_Type,PkgRecordsStruct) +NEW_FROM(PyPolicy_FromCpp,&PyPolicy_Type,pkgPolicy*) +NEW_FROM(PyProblemResolver_FromCpp,&PyProblemResolver_Type,pkgProblemResolver*) +NEW_FROM(PySourceList_FromCpp,&PySourceList_Type,pkgSourceList*) +//NEW_FROM(PySourceRecords_FromCpp,&PySourceRecords_Type,PkgSrcRecordsStruct) +NEW_FROM(PyTagFile_FromCpp,&PyTagFile_Type,pkgTagFile) +NEW_FROM(PyTagSection_FromCpp,&PyTagSection_Type,pkgTagSection) +NEW_FROM(PyVersion_FromCpp,&PyVersion_Type,pkgCache::VerIterator) + +#undef NEW_FROM diff --git a/python/python-apt.h b/python/python-apt.h new file mode 100644 index 0000000..e3c81b0 --- /dev/null +++ b/python/python-apt.h @@ -0,0 +1,368 @@ +/* + * python-apt.h - Header file for the public interface. + * + * Copyright 2009-2010 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef PYTHON_APT_H +#define PYTHON_APT_H +#include +#include "generic.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef PyObject *ActionGroupF(pkgDepCache::ActionGroup *); +typedef pkgDepCache::ActionGroup*& ActionGroupT(PyObject *self); + +struct _PyAptPkgAPIStruct { + // apt_pkg.Acquire (pkgAcquire*) + PyTypeObject *acquire_type; + PyObject* (*acquire_fromcpp)(pkgAcquire *acquire, bool Delete, PyObject*); + pkgAcquire*& (*acquire_tocpp)(PyObject *self); + // apt_pkg.AcquireFile + PyTypeObject *acquirefile_type; + PyObject* (*acquirefile_fromcpp)(pkgAcqFile* const &obj, bool Delete, PyObject *Owner); + pkgAcqFile*& (*acquirefile_tocpp)(PyObject *self); + + // apt_pkg.AcquireItem + PyTypeObject *acquireitem_type; + PyObject* (*acquireitem_fromcpp)(pkgAcquire::Item* const &obj, bool Delete, PyObject *Owner); + pkgAcquire::Item*& (*acquireitem_tocpp)(PyObject *self); + // apt_pkg.AcquireItemDesc + PyTypeObject *acquireitemdesc_type; + PyObject* (*acquireitemdesc_fromcpp)(pkgAcquire::ItemDesc* const &obj, bool Delete, PyObject *Owner); + pkgAcquire::ItemDesc*& (*acquireitemdesc_tocpp)(PyObject *self); + + PyTypeObject *acquireworker_type; + PyObject* (*acquireworker_fromcpp)(pkgAcquire::Worker* const &obj, bool Delete, PyObject *Owner); + pkgAcquire::Worker*& (*acquireworker_tocpp)(PyObject *self); + + PyTypeObject *actiongroup_type; + PyObject* (*actiongroup_fromcpp)(pkgDepCache::ActionGroup* const &obj, bool Delete, PyObject *Owner); + pkgDepCache::ActionGroup*& (*actiongroup_tocpp)(PyObject *self); + + PyTypeObject *cache_type; + PyObject* (*cache_fromcpp)(pkgCache* const &obj, bool Delete, PyObject *Owner); + pkgCache*& (*cache_tocpp)(PyObject *self); + + PyTypeObject *cachefile_type; + PyObject* (*cachefile_fromcpp)(pkgCacheFile* const &obj, bool Delete, PyObject *Owner); + pkgCacheFile*& (*cachefile_tocpp)(PyObject *self); + + PyTypeObject *cdrom_type; + PyObject* (*cdrom_fromcpp)(pkgCdrom const &obj, bool Delete, PyObject *Owner); + pkgCdrom& (*cdrom_tocpp)(PyObject *self); + + PyTypeObject *configuration_type; + PyObject* (*configuration_fromcpp)(Configuration* const &obj, bool Delete, PyObject *Owner); + Configuration*& (*configuration_tocpp)(PyObject *self); + + PyTypeObject *depcache_type; + PyObject* (*depcache_fromcpp)(pkgDepCache* const &obj, bool Delete, PyObject *Owner); + pkgDepCache*& (*depcache_tocpp)(PyObject *self); + + PyTypeObject *dependency_type; + PyObject* (*dependency_fromcpp)(pkgCache::DepIterator const &obj, bool Delete, PyObject *Owner); + pkgCache::DepIterator& (*dependency_tocpp)(PyObject *self); + + PyTypeObject *dependencylist_type; + void *dependencylist_fromcpp; // FIXME: need dependencylist_fromcpp + void *dependencylist_tocpp; // FIXME: need dependencylist_tocpp + + PyTypeObject *description_type; + PyObject* (*description_fromcpp)(pkgCache::DescIterator const &obj, bool Delete, PyObject *Owner); + pkgCache::DescIterator& (*description_tocpp)(PyObject *self); + + PyTypeObject *hashes_type; + PyObject* (*hashes_fromcpp)(Hashes const &obj, bool Delete, PyObject *Owner); + Hashes& (*hashes_tocpp)(PyObject *self); + + PyTypeObject *hashstring_type; + PyObject* (*hashstring_fromcpp)(HashString* const &obj, bool Delete, PyObject *Owner); + HashString*& (*hashstring_tocpp)(PyObject *self); + + PyTypeObject *metaindex_type; + PyObject* (*metaindex_fromcpp)(metaIndex* const &obj, bool Delete, PyObject *Owner); + metaIndex*& (*metaindex_tocpp)(PyObject *self); + + PyTypeObject *package_type; + PyObject* (*package_fromcpp)(pkgCache::PkgIterator const &obj, bool Delete, PyObject *Owner); + pkgCache::PkgIterator& (*package_tocpp)(PyObject *self); + + PyTypeObject *packagefile_type; + PyObject* (*packagefile_fromcpp)(pkgCache::PkgFileIterator const &obj, bool Delete, PyObject *Owner); + pkgCache::PkgFileIterator& (*packagefile_tocpp)(PyObject *self); + + PyTypeObject *packageindexfile_type; + PyObject* (*indexfile_fromcpp)(pkgIndexFile* const &obj, bool Delete, PyObject *Owner); + pkgIndexFile*& (*packageindexfile_tocpp)(PyObject *self); + + PyTypeObject *packagelist_type; + void *packagelist_fromcpp; // FIXME: need packagelist_fromcpp + void *packagelist_tocpp; // FIXME: need packagelist_tocpp + + PyTypeObject *packagemanager_type; + PyObject* (*packagemanager_fromcpp)(pkgPackageManager* const &obj, bool Delete, PyObject *Owner); + pkgPackageManager*& (*packagemanager_tocpp)(PyObject *self); + + PyTypeObject *packagerecords_type; + void *packagerecords_fromcpp; // FIXME: need packagerecords_fromcpp + void *packagerecords_tocpp; // FIXME: need packagerecords_tocpp + + PyTypeObject *policy_type; + PyObject* (*policy_fromcpp)(pkgPolicy* const &obj, bool Delete, PyObject *Owner); + pkgPolicy*& (*policy_tocpp)(PyObject *self); + + PyTypeObject *problemresolver_type; + PyObject* (*problemresolver_fromcpp)(pkgProblemResolver* const &obj, bool Delete, PyObject *Owner); + pkgProblemResolver*& (*problemresolver_tocpp)(PyObject *self); + + PyTypeObject *sourcelist_type; + PyObject* (*sourcelist_fromcpp)(pkgSourceList* const &obj, bool Delete, PyObject *Owner); + pkgSourceList*& (*sourcelist_tocpp)(PyObject *self); + + PyTypeObject *sourcerecords_type; + void *sourcerecords_fromcpp; // FIXME: need sourcerecords_fromcpp + void *sourcerecords_tocpp; // FIXME: need sourcerecords_tocpp + + PyTypeObject *tagfile_type; + PyObject* (*tagfile_fromcpp)(pkgTagFile const &obj, bool Delete, PyObject *Owner); + pkgTagFile& (*tagfile_tocpp)(PyObject *self); + + PyTypeObject *tagsection_type; + PyObject* (*tagsection_fromcpp)(pkgTagSection const &obj, bool Delete, PyObject *Owner); + pkgTagSection& (*tagsection_tocpp)(PyObject *self); + + PyTypeObject *version_type; + PyObject* (*version_fromcpp)(pkgCache::VerIterator const &obj, bool Delete, PyObject *Owner); + pkgCache::VerIterator& (*version_tocpp)(PyObject *self); + + PyTypeObject *group_type; + PyObject* (*group_fromcpp)(pkgCache::GrpIterator const &obj, bool Delete, PyObject *Owner); + pkgCache::GrpIterator& (*group_tocpp)(PyObject *self); + + PyTypeObject *orderlist_type; + PyObject* (*orderlist_fromcpp)(pkgOrderList* const &obj, bool Delete, PyObject *Owner); + pkgOrderList*& (*orderlist_tocpp)(PyObject *self); + + PyTypeObject *sourcerecordfiles_type; + void *sourcerecordfiles_fromcpp; // FIXME: need sourcerecordfiles_fromcpp + void *sourcerecordfiles_tocpp; // FIXME: need sourcerecordfiles_tocpp +}; + +// Checking macros. +# define PyAcquire_Check(op) PyObject_TypeCheck(op, &PyAcquire_Type) +# define PyAcquireFile_Check(op) PyObject_TypeCheck(op, &PyAcquireFile_Type) +# define PyAcquireItem_Check(op) PyObject_TypeCheck(op, &PyAcquireItem_Type) +# define PyAcquireItemDesc_Check(op) PyObject_TypeCheck(op, &PyAcquireItemDesc_Type) +# define PyAcquireWorker_Check(op) PyObject_TypeCheck(op, &PyAcquireWorker_Type) +# define PyActionGroup_Check(op) PyObject_TypeCheck(op, &PyActionGroup_Type) +# define PyCache_Check(op) PyObject_TypeCheck(op, &PyCache_Type) +# define PyCacheFile_Check(op) PyObject_TypeCheck(op, &PyCacheFile_Type) +# define PyCdrom_Check(op) PyObject_TypeCheck(op, &PyCdrom_Type) +# define PyConfiguration_Check(op) PyObject_TypeCheck(op, &PyConfiguration_Type) +# define PyDepCache_Check(op) PyObject_TypeCheck(op, &PyDepCache_Type) +# define PyDependency_Check(op) PyObject_TypeCheck(op, &PyDependency_Type) +# define PyDependencyList_Check(op) PyObject_TypeCheck(op, &PyDependencyList_Type) +# define PyDescription_Check(op) PyObject_TypeCheck(op, &PyDescription_Type) +# define PyGroup_Check(op) PyObject_TypeCheck(op, &PyGroup_Type) +# define PyHashes_Check(op) PyObject_TypeCheck(op, &PyHashes_Type) +# define PyHashString_Check(op) PyObject_TypeCheck(op, &PyHashString_Type) +# define PyIndexRecords_Check(op) PyObject_TypeCheck(op, &PyIndexRecords_Type) +# define PyMetaIndex_Check(op) PyObject_TypeCheck(op, &PyMetaIndex_Type) +# define PyPackage_Check(op) PyObject_TypeCheck(op, &PyPackage_Type) +# define PyPackageFile_Check(op) PyObject_TypeCheck(op, &PyPackageFile_Type) +# define PyIndexFile_Check(op) PyObject_TypeCheck(op, &PyIndexFile_Type) +# define PyPackageList_Check(op) PyObject_TypeCheck(op, &PyPackageList_Type) +# define PyPackageManager_Check(op) PyObject_TypeCheck(op, &PyPackageManager_Type) +# define PyPackageRecords_Check(op) PyObject_TypeCheck(op, &PyPackageRecords_Type) +# define PyPolicy_Check(op) PyObject_TypeCheck(op, &PyPolicy_Type) +# define PyProblemResolver_Check(op) PyObject_TypeCheck(op, &PyProblemResolver_Type) +# define PySourceList_Check(op) PyObject_TypeCheck(op, &PySourceList_Type) +# define PySourceRecords_Check(op) PyObject_TypeCheck(op, &PySourceRecords_Type) +# define PySourceRecordFiles_Check(op) PyObject_TypeCheck(op, &PySourceRecordFiles_Type) +# define PyTagFile_Check(op) PyObject_TypeCheck(op, &PyTagFile_Type) +# define PyTagSection_Check(op) PyObject_TypeCheck(op, &PyTagSection_Type) +# define PyVersion_Check(op) PyObject_TypeCheck(op, &PyVersion_Type) +// Exact check macros. +# define PyAcquire_CheckExact(op) (op->op_type == &PyAcquire_Type) +# define PyAcquireFile_CheckExact(op) (op->op_type == &PyAcquireFile_Type) +# define PyAcquireItem_CheckExact(op) (op->op_type == &PyAcquireItem_Type) +# define PyAcquireItemDesc_CheckExact(op) (op->op_type == &PyAcquireItemDesc_Type) +# define PyAcquireWorker_CheckExact(op) (op->op_type == &PyAcquireWorker_Type) +# define PyActionGroup_CheckExact(op) (op->op_type == &PyActionGroup_Type) +# define PyCache_CheckExact(op) (op->op_type == &PyCache_Type) +# define PyCacheFile_CheckExact(op) (op->op_type == &PyCacheFile_Type) +# define PyCdrom_CheckExact(op) (op->op_type == &PyCdrom_Type) +# define PyConfiguration_CheckExact(op) (op->op_type == &PyConfiguration_Type) +# define PyDepCache_CheckExact(op) (op->op_type == &PyDepCache_Type) +# define PyDependency_CheckExact(op) (op->op_type == &PyDependency_Type) +# define PyDependencyList_CheckExact(op) (op->op_type == &PyDependencyList_Type) +# define PyDescription_CheckExact(op) (op->op_type == &PyDescription_Type) +# define PyHashes_CheckExact(op) (op->op_type == &PyHashes_Type) +# define PyGroup_CheckExact(op) (op->op_type == &PyGroup_Type) +# define PyHashString_CheckExact(op) (op->op_type == &PyHashString_Type) +# define PyIndexRecords_CheckExact(op) (op->op_type == &PyIndexRecords_Type) +# define PyMetaIndex_CheckExact(op) (op->op_type == &PyMetaIndex_Type) +# define PyPackage_CheckExact(op) (op->op_type == &PyPackage_Type) +# define PyPackageFile_CheckExact(op) (op->op_type == &PyPackageFile_Type) +# define PyIndexFile_CheckExact(op) (op->op_type == &PyIndexFile_Type) +# define PyOrderList_CheckExact(op) (op->op_type == &PyOrderList_Type) +# define PyPackageList_CheckExact(op) (op->op_type == &PyPackageList_Type) +# define PyPackageManager_CheckExact(op) (op->op_type == &PyPackageManager_Type) +# define PyPackageRecords_CheckExact(op) (op->op_type == &PyPackageRecords_Type) +# define PyPolicy_CheckExact(op) (op->op_type == &PyPolicy_Type) +# define PyProblemResolver_CheckExact(op) (op->op_type == &PyProblemResolver_Type) +# define PySourceList_CheckExact(op) (op->op_type == &PySourceList_Type) +# define PySourceRecords_CheckExact(op) (op->op_type == &PySourceRecords_Type) +# define PySourceRecordFiles_CheckExact(op) (op->op_type == &PySourceRecordFiles_Type) +# define PyTagFile_CheckExact(op) (op->op_type == &PyTagFile_Type) +# define PyTagSection_CheckExact(op) (op->op_type == &PyTagSection_Type) +# define PyVersion_CheckExact(op) (op->op_type == &PyVersion_Type) + +# ifndef APT_PKGMODULE_H +static struct _PyAptPkgAPIStruct *_PyAptPkg_API; + +static int import_apt_pkg(void) { +# if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 1 + _PyAptPkg_API = (_PyAptPkgAPIStruct *)PyCapsule_Import("apt_pkg._C_API", 0); +# else + _PyAptPkg_API = (_PyAptPkgAPIStruct *)PyCObject_Import("apt_pkg", "_C_API"); +# endif // PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 1 + return (_PyAptPkg_API != NULL) ? 0 : -1; +} + +# define PyAcquire_Type *(_PyAptPkg_API->acquire_type) +# define PyAcquireFile_Type *(_PyAptPkg_API->acquirefile_type) +# define PyAcquireItem_Type *(_PyAptPkg_API->acquireitem_type) +# define PyAcquireItemDesc_Type *(_PyAptPkg_API->acquireitemdesc_type) +# define PyAcquireWorker_Type *(_PyAptPkg_API->acquireworker_type) +# define PyActionGroup_Type *(_PyAptPkg_API->actiongroup_type) +# define PyCache_Type *(_PyAptPkg_API->cache_type) +# define PyCacheFile_Type *(_PyAptPkg_API->cachefile_type) +# define PyCdrom_Type *(_PyAptPkg_API->cdrom_type) +# define PyConfiguration_Type *(_PyAptPkg_API->configuration_type) +# define PyDepCache_Type *(_PyAptPkg_API->depcache_type) +# define PyDependency_Type *(_PyAptPkg_API->dependency_type) +# define PyDependencyList_Type *(_PyAptPkg_API->dependencylist_type) +# define PyDescription_Type *(_PyAptPkg_API->description_type) +# define PyGroup_Type *(_PyAptPkg_API->group_type) +# define PyHashes_Type *(_PyAptPkg_API->hashes_type) +# define PyHashString_Type *(_PyAptPkg_API->hashstring_type) +# define PyIndexRecords_Type *(_PyAptPkg_API->indexrecords_type) +# define PyMetaIndex_Type *(_PyAptPkg_API->metaindex_type) +# define PyPackage_Type *(_PyAptPkg_API->package_type) +# define PyPackageFile_Type *(_PyAptPkg_API->packagefile_type) +# define PyIndexFile_Type *(_PyAptPkg_API->packageindexfile_type) +# define PyOrderList_Type *(_PyAptPkg_API->orderlist_type) +# define PyPackageList_Type *(_PyAptPkg_API->packagelist_type) +# define PyPackageManager_Type *(_PyAptPkg_API->packagemanager_type) +# define PyPackageRecords_Type *(_PyAptPkg_API->packagerecords_type) +# define PyPolicy_Type *(_PyAptPkg_API->policy_type) +# define PyProblemResolver_Type *(_PyAptPkg_API->problemresolver_type) +# define PySourceList_Type *(_PyAptPkg_API->sourcelist_type) +# define PySourceRecords_Type *(_PyAptPkg_API->sourcerecords_type) +# define PySourceRecordFiles_Type *(_PyAptPkg_API->sourcerecordfiles_type) +# define PyTagFile_Type *(_PyAptPkg_API->tagfile_type) +# define PyTagSection_Type *(_PyAptPkg_API->tagsection_type) +# define PyVersion_Type *(_PyAptPkg_API->version_type) +// Code +# define PyAcquire_ToCpp _PyAptPkg_API->acquire_tocpp +# define PyAcquireFile_ToCpp _PyAptPkg_API->acquirefile_tocpp +# define PyAcquireItem_ToCpp _PyAptPkg_API->acquireitem_tocpp +# define PyAcquireItemDesc_ToCpp _PyAptPkg_API->acquireitemdesc_tocpp +# define PyAcquireWorker_ToCpp _PyAptPkg_API->acquireworker_tocpp +# define PyActionGroup_ToCpp _PyAptPkg_API->actiongroup_tocpp +# define PyCache_ToCpp _PyAptPkg_API->cache_tocpp +# define PyCacheFile_ToCpp _PyAptPkg_API->cachefile_tocpp +# define PyCdrom_ToCpp _PyAptPkg_API->cdrom_tocpp +# define PyConfiguration_ToCpp _PyAptPkg_API->configuration_tocpp +# define PyDepCache_ToCpp _PyAptPkg_API->depcache_tocpp +# define PyDependency_ToCpp _PyAptPkg_API->dependency_tocpp +# define PyDependencyList_ToCpp _PyAptPkg_API->dependencylist_tocpp // NULL +# define PyDescription_ToCpp _PyAptPkg_API->description_tocpp +# define PyGroup_ToCpp _PyAptPkg_API->group_tocpp +# define PyHashes_ToCpp _PyAptPkg_API->hashes_tocpp +# define PyHashString_ToCpp _PyAptPkg_API->hashstring_tocpp +# define PyIndexRecords_ToCpp _PyAptPkg_API->indexrecords_tocpp +# define PyMetaIndex_ToCpp _PyAptPkg_API->metaindex_tocpp +# define PyPackage_ToCpp _PyAptPkg_API->package_tocpp +# define PyPackageFile_ToCpp _PyAptPkg_API->packagefile_tocpp +# define PyIndexFile_ToCpp _PyAptPkg_API->packageindexfile_tocpp +# define PyOrderList_ToCpp _PyAptPkg_API->orderlist_tocpp // NULL +# define PyPackageList_ToCpp _PyAptPkg_API->packagelist_tocpp // NULL +# define PyPackageManager_ToCpp _PyAptPkg_API->packagemanager_tocpp +# define PyPackageRecords_ToCpp _PyAptPkg_API->packagerecords_tocpp +# define PyPolicy_ToCpp _PyAptPkg_API->policy_tocpp +# define PyProblemResolver_ToCpp _PyAptPkg_API->problemresolver_tocpp +# define PySourceList_ToCpp _PyAptPkg_API->sourcelist_tocpp +# define PySourceRecords_ToCpp _PyAptPkg_API->sourcerecords_tocpp // NULL +# define PySourceRecordFiles_ToCpp _PyAptPkg_API->sourcerecordfiles_tocpp // NULL +# define PyTagFile_ToCpp _PyAptPkg_API->tagfile_tocpp +# define PyTagSection_ToCpp _PyAptPkg_API->tagsection_tocpp +# define PyVersion_ToCpp _PyAptPkg_API->version_tocpp +// Get the C++ object +# define PyAcquire_FromCpp _PyAptPkg_API->acquire_fromcpp +# define PyAcquireFile_FromCpp _PyAptPkg_API->acquirefile_fromcpp +# define PyAcquireItem_FromCpp _PyAptPkg_API->acquireitem_fromcpp +# define PyAcquireItemDesc_FromCpp _PyAptPkg_API->acquireitemdesc_fromcpp +# define PyAcquireWorker_FromCpp _PyAptPkg_API->acquireworker_fromcpp +# define PyActionGroup_FromCpp _PyAptPkg_API->actiongroup_fromcpp +# define PyCache_FromCpp _PyAptPkg_API->cache_fromcpp +# define PyCacheFile_FromCpp _PyAptPkg_API->cachefile_fromcpp +# define PyCdrom_FromCpp _PyAptPkg_API->cdrom_fromcpp +# define PyConfiguration_FromCpp _PyAptPkg_API->configuration_fromcpp +# define PyDepCache_FromCpp _PyAptPkg_API->depcache_fromcpp +# define PyDependency_FromCpp _PyAptPkg_API->dependency_fromcpp +# define PyDependencyList_FromCpp _PyAptPkg_API->dependencylist_fromcpp // NULL +# define PyDescription_FromCpp _PyAptPkg_API->description_fromcpp +# define PyGroup_FromCpp _PyAptPkg_API->group_fromcpp +# define PyHashes_FromCpp _PyAptPkg_API->hashes_fromcpp +# define PyHashString_FromCpp _PyAptPkg_API->hashstring_fromcpp +# define PyIndexRecords_FromCpp _PyAptPkg_API->indexrecords_fromcpp +# define PyMetaIndex_FromCpp _PyAptPkg_API->metaindex_fromcpp +# define PyPackage_FromCpp _PyAptPkg_API->package_fromcpp +# define PyPackageFile_FromCpp _PyAptPkg_API->packagefile_fromcpp +# define PyIndexFile_FromCpp _PyAptPkg_API->packageindexfile_fromcpp +# define PyOrderList_FromCpp _PyAptPkg_API->orderlist_fromcpp // NULL +# define PyPackageList_FromCpp _PyAptPkg_API->packagelist_fromcpp // NULL +# define PyPackageManager_FromCpp _PyAptPkg_API->packagemanager_fromcpp +# define PyPackageRecords_FromCpp _PyAptPkg_API->packagerecords_fromcpp +# define PyPolicy_FromCpp _PyAptPkg_API->policy_fromcpp +# define PyProblemResolver_FromCpp _PyAptPkg_API->problemresolver_fromcpp +# define PySourceList_FromCpp _PyAptPkg_API->sourcelist_fromcpp +# define PySourceRecords_FromCpp _PyAptPkg_API->sourcerecords_fromcpp // NULL +# define PySourceRecordFiles_FromCpp _PyAptPkg_API->sourcerecordfiles_fromcpp // NULL +# define PyTagFile_FromCpp _PyAptPkg_API->tagfile_fromcpp +# define PyTagSection_FromCpp _PyAptPkg_API->tagsection_fromcpp +# define PyVersion_FromCpp _PyAptPkg_API->version_fromcpp +# endif // APT_PKGMODULE_H + +#endif + diff --git a/python/sourcelist.cc b/python/sourcelist.cc new file mode 100644 index 0000000..3c1d49c --- /dev/null +++ b/python/sourcelist.cc @@ -0,0 +1,170 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: sourcelist.cc,v 1.2 2003/12/26 17:04:22 mdz Exp $ +/* ###################################################################### + + SourcesList - Wrapper for the SourcesList functions + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "generic.h" +#include "apt_pkgmodule.h" + +#include + +#include + /*}}}*/ + + + +// PkgsourceList Class /*{{{*/ +// --------------------------------------------------------------------- + +static char *doc_PkgSourceListFindIndex = + "find_index(pkgfile: apt_pkg.PackageFile) -> apt_pkg.IndexFile\n\n" + "Return the index file for the given package file, or None if none\n" + "could be found."; +static PyObject *PkgSourceListFindIndex(PyObject *Self,PyObject *Args) +{ + pkgSourceList *list = GetCpp(Self); + PyObject *pyPkgFileIter; + CppPyObject *pyPkgIndexFile; + + if (PyArg_ParseTuple(Args, "O!", &PyPackageFile_Type,&pyPkgFileIter) == 0) + return 0; + + pkgCache::PkgFileIterator &i = GetCpp(pyPkgFileIter); + pkgIndexFile *index; + if(list->FindIndex(i, index)) + { + pyPkgIndexFile = CppPyObject_NEW(pyPkgFileIter,&PyIndexFile_Type,index); + // Do not delete the pkgIndexFile*, it is managed by pkgSourceList. + pyPkgIndexFile->NoDelete = true; + return pyPkgIndexFile; + } + + //&PyIndexFile_Type,&pyPkgIndexFile) + + Py_INCREF(Py_None); + return Py_None; +} + +static char *doc_PkgSourceListReadMainList = + "read_main_list() -> bool\n\n" + "Read /etc/apt/sources.list and similar files to populate the list\n" + "of indexes."; +static PyObject *PkgSourceListReadMainList(PyObject *Self,PyObject *Args) +{ + pkgSourceList *list = GetCpp(Self); + bool res = list->ReadMainList(); + + return HandleErrors(PyBool_FromLong(res)); +} + +static char *doc_PkgSourceListGetIndexes = + "get_indexes(acquire: apt_pkg.Acquire[, all: bool=False]) -> bool\n\n" + "Add all indexes (i.e. stuff like Release files, Packages files)\n" + "to the Acquire object 'acquire'. If 'all' is True, all indexes\n" + "will be added, otherwise only changed indexes will be added."; +static PyObject *PkgSourceListGetIndexes(PyObject *Self,PyObject *Args) +{ + pkgSourceList *list = GetCpp(Self); + + PyObject *pyFetcher; + char all = 0; + if (PyArg_ParseTuple(Args, "O!|b",&PyAcquire_Type,&pyFetcher, &all) == 0) + return 0; + + pkgAcquire *fetcher = GetCpp(pyFetcher); + bool res = list->GetIndexes(fetcher, all); + + return HandleErrors(PyBool_FromLong(res)); +} + +static PyMethodDef PkgSourceListMethods[] = +{ + {"find_index",PkgSourceListFindIndex,METH_VARARGS,doc_PkgSourceListFindIndex}, + {"read_main_list",PkgSourceListReadMainList,METH_VARARGS,doc_PkgSourceListReadMainList}, + {"get_indexes",PkgSourceListGetIndexes,METH_VARARGS,doc_PkgSourceListGetIndexes}, + {} +}; + +static PyObject *PkgSourceListGetList(PyObject *Self,void*) +{ + pkgSourceList *list = GetCpp(Self); + PyObject *List = PyList_New(0); + for (std::vector::const_iterator I = list->begin(); + I != list->end(); I++) + { + CppPyObject *Obj; + Obj = CppPyObject_NEW(Self, &PyMetaIndex_Type,*I); + // Never delete metaIndex*, they are managed by the pkgSourceList. + Obj->NoDelete = true; + PyList_Append(List,Obj); + Py_DECREF(Obj); + } + return List; +} + +static PyGetSetDef PkgSourceListGetSet[] = { + {"list",PkgSourceListGetList,0,"A list of MetaIndex() objects.",0}, + {} +}; + +static PyObject *PkgSourceListNew(PyTypeObject *type,PyObject *args,PyObject *kwds) +{ + char *kwlist[] = {0}; + if (PyArg_ParseTupleAndKeywords(args,kwds,"",kwlist) == 0) + return 0; + return CppPyObject_NEW(NULL, type,new pkgSourceList()); +} + +static const char *sourcelist_doc = + "SourceList()\n\n" + "Represent the list of sources stored in /etc/apt/sources.list and\n" + "similar files."; +PyTypeObject PySourceList_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.SourceList", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDeallocPtr, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE), + sourcelist_doc, // tp_doc + 0, // tp_traverse + 0, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + PkgSourceListMethods, // tp_methods + 0, // tp_members + PkgSourceListGetSet, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PkgSourceListNew, // tp_new +}; + diff --git a/python/string.cc b/python/string.cc new file mode 100644 index 0000000..7cfaa70 --- /dev/null +++ b/python/string.cc @@ -0,0 +1,142 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: string.cc,v 1.3 2002/01/08 06:53:04 jgg Exp $ +/* ###################################################################### + + string - Mappings for the string functions that are worthwile for + Python users + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "apt_pkgmodule.h" +#include "generic.h" + +#include + +#include + /*}}}*/ + +// Templated function /*{{{*/ +/* Macro for the generic string in string out function */ +#define MkStr(Python,CFunc) \ +PyObject *Python(PyObject *Self,PyObject *Args) \ +{ \ + char *Str = 0; \ + if (PyArg_ParseTuple(Args,"s",&Str) == 0) \ + return 0; \ + return CppPyString(CFunc(Str)); \ +} + +#define MkInt(Python,CFunc, ctype, pytype, ...) \ +PyObject *Python(PyObject *Self,PyObject *Args) \ +{ \ + ctype Val = 0; \ + if (PyArg_ParseTuple(Args,pytype,&Val) == 0) \ + return 0; \ + return CppPyString(CFunc(Val, ##__VA_ARGS__)); \ +} + +MkStr(StrDeQuote,DeQuoteString); + +/* + * Input bytes(Py3k)/str(Py2), output str. + */ +PyObject *StrBase64Encode(PyObject *Self,PyObject *Args) { + char *Str = 0; + #if PY_MAJOR_VERSION >= 3 + if (PyArg_ParseTuple(Args,"y",&Str) == 0) + #else + if (PyArg_ParseTuple(Args,"s",&Str) == 0) + #endif + return 0; + return CppPyString(Base64Encode(Str)); +} + +PyObject *StrURItoFileName(PyObject *Self,PyObject *Args) +{ + char *Str = 0; + if (PyArg_ParseTuple(Args,"s",&Str) == 0) + return 0; + return CppPyPath(URItoFileName(Str)); +} + +//MkFloat(StrSizeToStr,SizeToStr); +MkInt(StrTimeToStr,TimeToStr, unsigned long, "k"); +MkInt(StrTimeRFC1123,TimeRFC1123, long long, "L", false); + /*}}}*/ + +// Other String functions /*{{{*/ +PyObject *StrSizeToStr(PyObject *Self,PyObject *Args) +{ + PyObject *Obj; + double value; + + if (PyArg_ParseTuple(Args,"O",&Obj) == 0) + return 0; + // In Python 3, PyInt_Check is aliased to PyLong_Check and PyInt_AsLong is + // aliased to PyLong_AsLong. Therefore we do the actual long checks first + // so that if it is a long in Python 3, the value will be converted to a + // double rather than a long. This avoids OverflowError regressions in + // Python 3. LP: #1030278 + if (PyLong_Check(Obj)) + value = PyLong_AsDouble(Obj); + else if (PyInt_Check(Obj)) + value = PyInt_AsLong(Obj); + else if (PyFloat_Check(Obj)) + value = PyFloat_AsDouble(Obj); + else { + PyErr_SetString(PyExc_TypeError,"Only understand integers and floats"); + return 0; + } + // Check for OverflowErrors or other exceptions during conversion. + if (PyErr_Occurred()) + return 0; + return CppPyString(SizeToStr(value)); +} + +PyObject *StrQuoteString(PyObject *Self,PyObject *Args) +{ + char *Str = 0; + char *Bad = 0; + if (PyArg_ParseTuple(Args,"ss",&Str,&Bad) == 0) + return 0; + return CppPyString(QuoteString(Str,Bad)); +} + +PyObject *StrStringToBool(PyObject *Self,PyObject *Args) +{ + char *Str = 0; + if (PyArg_ParseTuple(Args,"s",&Str) == 0) + return 0; + return MkPyNumber(StringToBool(Str)); +} + +PyObject *StrStrToTime(PyObject *Self,PyObject *Args) +{ + char *Str = 0; + if (PyArg_ParseTuple(Args,"s",&Str) == 0) + return 0; + + time_t Result; +APT_IGNORE_DEPRECATED_PUSH + if (RFC1123StrToTime(Str,Result) == false) + { +APT_IGNORE_DEPRECATED_POP + Py_INCREF(Py_None); + return Py_None; + } + + return MkPyNumber(Result); +} + +PyObject *StrCheckDomainList(PyObject *Self,PyObject *Args) +{ + char *Host = 0; + char *List = 0; + if (PyArg_ParseTuple(Args,"ss",&Host,&List) == 0) + return 0; + return PyBool_FromLong(CheckDomainList(Host,List)); +} + + /*}}}*/ diff --git a/python/tag.cc b/python/tag.cc new file mode 100644 index 0000000..691b67f --- /dev/null +++ b/python/tag.cc @@ -0,0 +1,1063 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: tag.cc,v 1.3 2002/02/26 01:36:15 mdz Exp $ +/* ###################################################################### + + Tag - Binding for the RFC 822 tag file parser + + Upon reflection I have make the TagSection wrapper look like a map.. + The other option was to use a sequence (which nicely matches the internal + storage) but really makes no sense to a Python Programmer.. One + specialized lookup is provided, the FindFlag lookup - as well as the + usual set of duplicate things to match the C++ interface. + + The TagFile interface is also slightly different, it has a built in + internal TagSection object that is used. Do not hold onto a reference + to a TagSection and let TagFile go out of scope! The underlying storage + for the section will go away and it will seg. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#include "generic.h" +#include "apt_pkgmodule.h" + +#include +#include + +#include +#include +#include + +using namespace std; + /*}}}*/ +/* We need to keep a private copy of the data.. */ +struct TagSecData : public CppPyObject +{ + char *Data; + bool Bytes; +#if PY_MAJOR_VERSION >= 3 + PyObject *Encoding; +#endif +}; + +// The owner of the TagFile is a Python file object. +struct TagFileData : public CppPyObject +{ + TagSecData *Section; + FileFd Fd; + bool Bytes; +#if PY_MAJOR_VERSION >= 3 + PyObject *Encoding; +#endif +}; + +// Traversal and Clean for owned objects +int TagFileTraverse(PyObject *self, visitproc visit, void* arg) { + Py_VISIT(((TagFileData *)self)->Section); + Py_VISIT(((TagFileData *)self)->Owner); + return 0; +} + +int TagFileClear(PyObject *self) { + Py_CLEAR(((TagFileData *)self)->Section); + Py_CLEAR(((TagFileData *)self)->Owner); + return 0; +} + +// Helpers to return Unicode or bytes as appropriate. +#if PY_MAJOR_VERSION < 3 +#define TagSecString_FromStringAndSize(self, v, len) \ + PyString_FromStringAndSize((v), (len)) +#define TagSecString_FromString(self, v) CppPyString(v) +#else +static PyObject *TagSecString_FromStringAndSize(PyObject *self, const char *v, + Py_ssize_t len) { + TagSecData *Self = (TagSecData *)self; + if (Self->Bytes) + return PyBytes_FromStringAndSize(v, len); + else if (Self->Encoding) + return PyUnicode_Decode(v, len, PyUnicode_AsString(Self->Encoding), 0); + else + return PyUnicode_FromStringAndSize(v, len); +} + +static PyObject *TagSecString_FromString(PyObject *self, const char *v) { + TagSecData *Self = (TagSecData *)self; + if (Self->Bytes) + return PyBytes_FromString(v); + else if (Self->Encoding) + return PyUnicode_Decode(v, strlen(v), + PyUnicode_AsString(Self->Encoding), 0); + else + return PyUnicode_FromString(v); +} +#endif + + + /*}}}*/ +// TagSecFree - Free a Tag Section /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void TagSecFree(PyObject *Obj) +{ + TagSecData *Self = (TagSecData *)Obj; + delete [] Self->Data; + CppDealloc(Obj); +} + /*}}}*/ +// TagFileFree - Free a Tag File /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void TagFileFree(PyObject *Obj) +{ + #ifdef ALLOC_DEBUG + std::cerr << "=== DEALLOCATING " << Obj->ob_type->tp_name << "^ ===\n"; + #endif + PyObject_GC_UnTrack(Obj); + TagFileData *Self = (TagFileData *)Obj; + Py_CLEAR(Self->Section); + Self->Object.~pkgTagFile(); + Self->Fd.~FileFd(); + Py_CLEAR(Self->Owner); + Obj->ob_type->tp_free(Obj); +} + /*}}}*/ + +// Tag Section Wrappers /*{{{*/ +static char *doc_Find = + "find(name: str[, default = None]) -> str\n\n" + "Find the key given by 'name' and return the value. If the key can\n" + "not be found, return 'default'."; +static PyObject *TagSecFind(PyObject *Self,PyObject *Args) +{ + char *Name = 0; + char *Default = 0; + if (PyArg_ParseTuple(Args,"s|z",&Name,&Default) == 0) + return 0; + + const char *Start; + const char *Stop; + if (GetCpp(Self).Find(Name,Start,Stop) == false) + { + if (Default == 0) + Py_RETURN_NONE; + return TagSecString_FromString(Self,Default); + } + return TagSecString_FromStringAndSize(Self,Start,Stop-Start); +} + +static char *doc_FindRaw = + "find_raw(name: str[, default = None] -> str\n\n" + "Same as find(), but returns the complete 'key: value' field; instead of\n" + "just the value."; +static PyObject *TagSecFindRaw(PyObject *Self,PyObject *Args) +{ + char *Name = 0; + char *Default = 0; + if (PyArg_ParseTuple(Args,"s|z",&Name,&Default) == 0) + return 0; + + unsigned Pos; + if (GetCpp(Self).Find(Name,Pos) == false) + { + if (Default == 0) + Py_RETURN_NONE; + return TagSecString_FromString(Self,Default); + } + + const char *Start; + const char *Stop; + GetCpp(Self).Get(Start,Stop,Pos); + + return TagSecString_FromStringAndSize(Self,Start,Stop-Start); +} + +static char *doc_FindFlag = + "find_flag(name: str) -> int\n\n" + "Return 1 if the key's value is 'yes' or a similar value describing\n" + "a boolean true. If the field does not exist, or does not have such a\n" + "value, return 0."; +static PyObject *TagSecFindFlag(PyObject *Self,PyObject *Args) +{ + char *Name = 0; + if (PyArg_ParseTuple(Args,"s",&Name) == 0) + return 0; + + unsigned long Flag = 0; + if (GetCpp(Self).FindFlag(Name,Flag,1) == false) + { + Py_INCREF(Py_None); + return Py_None; + } + return PyBool_FromLong(Flag); +} + +static char *doc_Write = + "write(file: int, order: List[str], rewrite: List[Tag]) -> None\n\n" + "Rewrites the section into the given file descriptor, which should be\n" + "a file descriptor or an object providing a fileno() method.\n" + "\n" + ".. versionadded:: 1.9.0"; +static PyObject *TagSecWrite(PyObject *Self, PyObject *Args, PyObject *kwds) +{ + char *kwlist[] = {"file", "order", "rewrite", nullptr}; + PyObject *pFile; + PyObject *pOrder; + PyObject *pRewrite; + if (PyArg_ParseTupleAndKeywords(Args,kwds, "OO!O!",kwlist, &pFile,&PyList_Type,&pOrder, &PyList_Type, &pRewrite) == 0) + return nullptr; + + int fileno = PyObject_AsFileDescriptor(pFile); + // handle invalid arguments + if (fileno == -1) + { + PyErr_SetString(PyExc_TypeError, + "Argument must be string, fd or have a fileno() method"); + return 0; + } + + FileFd file(fileno); + const char **order = ListToCharChar(pOrder,true); + if (order == nullptr) + return nullptr; + std::vector rewrite; + for (int I = 0; I != PySequence_Length(pRewrite); I++) { + PyObject *item = PySequence_GetItem(pRewrite, I); + if (!PyObject_TypeCheck(item, &PyTag_Type)) + return PyErr_SetString(PyExc_TypeError, "Wrong type for tag in list"), nullptr; + rewrite.push_back(GetCpp(item)); + } + + return HandleErrors(PyBool_FromLong(GetCpp(Self).Write(file, order, rewrite))); +} + + +// Map access, operator [] +static PyObject *TagSecMap(PyObject *Self,PyObject *Arg) +{ + const char *Name = PyObject_AsString(Arg); + if (Name == 0) + return 0; + const char *Start; + const char *Stop; + if (GetCpp(Self).Find(Name,Start,Stop) == false) + { + PyErr_SetString(PyExc_KeyError,Name); + return 0; + } + + return TagSecString_FromStringAndSize(Self,Start,Stop-Start); +} + +// len() operation +static Py_ssize_t TagSecLength(PyObject *Self) +{ + pkgTagSection &Sec = GetCpp(Self); + return Sec.Count(); +} + +// Look like a mapping +static char *doc_Keys = + "keys() -> list\n\n" + "Return a list of all keys."; +static PyObject *TagSecKeys(PyObject *Self,PyObject *Args) +{ + pkgTagSection &Tags = GetCpp(Self); + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + // Convert the whole configuration space into a list + PyObject *List = PyList_New(0); + for (unsigned int I = 0; I != Tags.Count(); I++) + { + const char *Start; + const char *Stop; + Tags.Get(Start,Stop,I); + const char *End = Start; + for (; End < Stop && *End != ':'; End++); + + PyObject *Obj; + PyList_Append(List,Obj = PyString_FromStringAndSize(Start,End-Start)); + Py_DECREF(Obj); + } + return List; +} + +#if PY_MAJOR_VERSION < 3 +static char *doc_Exists = + "has_key(name: str) -> bool\n\n" + "Return True if the key given by 'name' exists, False otherwise."; +static PyObject *TagSecExists(PyObject *Self,PyObject *Args) +{ + char *Name = 0; + if (PyArg_ParseTuple(Args,"s",&Name) == 0) + return 0; + + const char *Start; + const char *Stop; + return PyBool_FromLong(GetCpp(Self).Find(Name,Start,Stop)); +} +#endif + +static int TagSecContains(PyObject *Self,PyObject *Arg) +{ + const char *Name = PyObject_AsString(Arg); + if (Name == 0) + return 0; + const char *Start; + const char *Stop; + if (GetCpp(Self).Find(Name,Start,Stop) == false) + return 0; + return 1; +} + +static char *doc_Bytes = + "bytes() -> int\n\n" + "Return the number of bytes this section is large."; +static PyObject *TagSecBytes(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + return MkPyNumber(GetCpp(Self).size()); +} + +static PyObject *TagSecStr(PyObject *Self) +{ + const char *Start; + const char *Stop; + GetCpp(Self).GetSection(Start,Stop); + return TagSecString_FromStringAndSize(Self,Start,Stop-Start); +} + /*}}}*/ +// TagFile Wrappers /*{{{*/ +static char *doc_Step = + "step() -> bool\n\n" + "Step forward in the file"; +static PyObject *TagFileStep(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + + TagFileData &Obj = *(TagFileData *)Self; + if (Obj.Object.Step(Obj.Section->Object) == false) + return HandleErrors(PyBool_FromLong(0)); + + return HandleErrors(PyBool_FromLong(1)); +} + +// TagFile Wrappers /*{{{*/ +static PyObject *TagFileNext(PyObject *Self) +{ + TagFileData &Obj = *(TagFileData *)Self; + // Replace the section. + Py_CLEAR(Obj.Section); + Obj.Section = (TagSecData*)(&PyTagSection_Type)->tp_alloc(&PyTagSection_Type, 0); + new (&Obj.Section->Object) pkgTagSection(); + Obj.Section->Owner = Self; + Py_INCREF(Obj.Section->Owner); + Obj.Section->Data = 0; + Obj.Section->Bytes = Obj.Bytes; +#if PY_MAJOR_VERSION >= 3 + // We don't need to incref Encoding as the previous Section object already + // held a reference to it. + Obj.Section->Encoding = Obj.Encoding; +#endif + if (Obj.Object.Step(Obj.Section->Object) == false) + return HandleErrors(NULL); + + // Bug-Debian: http://bugs.debian.org/572596 + // Duplicate the data here and scan the duplicated section data; in order + // to not use any shared storage. + // TODO: Provide an API in apt-pkg to do this; this is really ugly. + + // Fetch old section data + const char *Start; + const char *Stop; + Obj.Section->Object.GetSection(Start,Stop); + // Duplicate the data and + // append a \n because GetSection() will only give us a single \n + // but Scan() needs \n\n to work + Obj.Section->Data = new char[Stop-Start+2]; + + memcpy(Obj.Section->Data, Start, Stop - Start); + Obj.Section->Data[Stop-Start] = '\n'; + Obj.Section->Data[Stop-Start+1] = '\0'; + // Rescan it + if(Obj.Section->Object.Scan(Obj.Section->Data, Stop-Start+2) == false) + return HandleErrors(NULL); + + Py_INCREF(Obj.Section); + return HandleErrors(Obj.Section); +} + +static PyObject *TagFileIter(PyObject *Self) { + Py_INCREF(Self); + return Self; +} + +static char *doc_Offset = + "offset() -> int\n\n" + "Return the current offset."; +static PyObject *TagFileOffset(PyObject *Self,PyObject *Args) +{ + if (PyArg_ParseTuple(Args,"") == 0) + return 0; + return MkPyNumber(((TagFileData *)Self)->Object.Offset()); + +} + +static char *doc_Jump = + "jump(offset: int) -> bool\n\n" + "Jump to the given offset; return True on success. Note that jumping to\n" + "an offset is not very reliable, and the 'section' attribute may point\n" + "to an unexpected section."; +static PyObject *TagFileJump(PyObject *Self,PyObject *Args) +{ + int Offset; + if (PyArg_ParseTuple(Args,"i",&Offset) == 0) + return 0; + + TagFileData &Obj = *(TagFileData *)Self; + if (Obj.Object.Jump(Obj.Section->Object,Offset) == false) + return HandleErrors(PyBool_FromLong(0)); + + return HandleErrors(PyBool_FromLong(1)); +} + +static char *doc_Close = + "close()\n\n" + "Close the file."; +static PyObject *TagFileClose(PyObject *self, PyObject *args) +{ + if (args != NULL && !PyArg_ParseTuple(args, "")) + return NULL; + + TagFileData &Obj = *(TagFileData *) self; + + Obj.Fd.Close(); + + Py_INCREF(Py_None); + return HandleErrors(Py_None); +} + +static PyObject *TagFileExit(PyObject *self, PyObject *args) +{ + + PyObject *exc_type = 0; + PyObject *exc_value = 0; + PyObject *traceback = 0; + if (!PyArg_UnpackTuple(args, "__exit__", 3, 3, &exc_type, &exc_value, + &traceback)) { + return 0; + } + + PyObject *res = TagFileClose(self, NULL); + + if (res == NULL) { + // The close failed. If no exception happened within the suite, we + // will raise an error here. Otherwise, we just display the error, so + // Python can handle the original exception instead. + if (exc_type == Py_None) + return NULL; + + PyErr_WriteUnraisable(self); + } else { + Py_DECREF(res); + } + // Return False, as required by the context manager protocol. + Py_RETURN_FALSE; +} + +static PyObject *TagFileEnter(PyObject *self, PyObject *args) +{ + if (!PyArg_ParseTuple(args, "")) + return NULL; + + Py_INCREF(self); + + return self; +} + + /*}}}*/ +// ParseSection - Parse a single section from a tag file /*{{{*/ +// --------------------------------------------------------------------- +static PyObject *TagSecNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) { + char *Data; + Py_ssize_t Len; + char Bytes = 0; + char *kwlist[] = {"text", "bytes", 0}; + + // this allows reading "byte" types from python3 - but we don't + // make (much) use of it yet + if (PyArg_ParseTupleAndKeywords(Args,kwds,"s#|b",kwlist,&Data,&Len,&Bytes) == 0) + return 0; + if (memchr(Data, 0, Len) != nullptr) { + PyErr_SetString(PyExc_ValueError, "Input contains NUL byte"); + return 0; + } + if (Data[Len] != 0) { + PyErr_SetString(PyExc_ValueError, "Input is not terminated by NUL byte"); + return 0; + } + + // Create the object.. + TagSecData *New = (TagSecData*)type->tp_alloc(type, 0); + new (&New->Object) pkgTagSection(); + New->Data = new char[strlen(Data)+2]; + snprintf(New->Data,strlen(Data)+2,"%s\n",Data); + New->Bytes = Bytes; +#if PY_MAJOR_VERSION >= 3 + New->Encoding = 0; +#endif + + if (New->Object.Scan(New->Data,strlen(New->Data)) == false) + { + cerr << New->Data << endl; + Py_DECREF((PyObject *)New); + PyErr_SetString(PyExc_ValueError,"Unable to parse section data"); + return 0; + } + + New->Object.Trim(); + + return New; +} + + /*}}}*/ +// ParseTagFile - Parse a tagd file /*{{{*/ +// --------------------------------------------------------------------- +/* This constructs the parser state. */ + +static PyObject *TagFileNew(PyTypeObject *type,PyObject *Args,PyObject *kwds) +{ + PyObject *File = 0; + char Bytes = 0; + + char *kwlist[] = {"file", "bytes", 0}; + if (PyArg_ParseTupleAndKeywords(Args,kwds,"O|b",kwlist,&File,&Bytes) == 0) + return 0; + + // check if we got a filename or a file object + int fileno = -1; + PyApt_Filename filename; + if (!filename.init(File)) { + PyErr_Clear(); + fileno = PyObject_AsFileDescriptor(File); + } + + // handle invalid arguments + if (fileno == -1 && filename == NULL) + { + PyErr_SetString(PyExc_TypeError, + "Argument must be string, fd or have a fileno() method"); + return 0; + } + + PyApt_UniqueObject New((TagFileData*)type->tp_alloc(type, 0)); + if (fileno != -1) + { +#ifdef APT_HAS_GZIP + new (&New->Fd) FileFd(); + New->Fd.OpenDescriptor(fileno, FileFd::ReadOnlyGzip, false); +#else + new (&New->Fd) FileFd(fileno,false); +#endif + } + else + { + // FileFd::Extension got added in this revision +#if (APT_PKG_MAJOR > 4 || (APT_PKG_MAJOR >= 4 && APT_PKG_MINOR >= 12)) + new (&New->Fd) FileFd(filename, FileFd::ReadOnly, FileFd::Extension, false); +#else + new (&New->Fd) FileFd(filename, FileFd::ReadOnly, false); +#endif + } + New->Bytes = Bytes; + New->Owner = File; + Py_INCREF(New->Owner); +#if PY_MAJOR_VERSION >= 3 + if (fileno != -1) { + New->Encoding = PyObject_GetAttr(File, PyUnicode_FromString("encoding")); + if (!New->Encoding) + PyErr_Clear(); + if (New->Encoding && !PyUnicode_Check(New->Encoding)) + New->Encoding = 0; + } else + New->Encoding = 0; + Py_XINCREF(New->Encoding); +#endif + new (&New->Object) pkgTagFile(&New->Fd); + + // Create the section + New->Section = (TagSecData*)(&PyTagSection_Type)->tp_alloc(&PyTagSection_Type, 0); + new (&New->Section->Object) pkgTagSection(); + New->Section->Owner = New.get(); + Py_INCREF(New->Section->Owner); + New->Section->Data = 0; + New->Section->Bytes = Bytes; +#if PY_MAJOR_VERSION >= 3 + New->Section->Encoding = New->Encoding; + Py_XINCREF(New->Section->Encoding); +#endif + + return HandleErrors(New.release()); +} + /*}}}*/ + +// Method table for the Tag Section object +static PyMethodDef TagSecMethods[] = +{ + // Query + {"find",TagSecFind,METH_VARARGS,doc_Find}, + {"find_raw",TagSecFindRaw,METH_VARARGS,doc_FindRaw}, + {"find_flag",TagSecFindFlag,METH_VARARGS,doc_FindFlag}, + {"bytes",TagSecBytes,METH_VARARGS,doc_Bytes}, + {"write",(PyCFunction) TagSecWrite,METH_VARARGS|METH_KEYWORDS,doc_Write}, + + // Python Special + {"keys",TagSecKeys,METH_VARARGS,doc_Keys}, +#if PY_MAJOR_VERSION < 3 + {"has_key",TagSecExists,METH_VARARGS,doc_Exists}, +#endif + {"get",TagSecFind,METH_VARARGS,doc_Find}, + {} +}; + + +PySequenceMethods TagSecSeqMeth = {0,0,0,0,0,0,0,TagSecContains,0,0}; +PyMappingMethods TagSecMapMeth = {TagSecLength,TagSecMap,0}; + + +static char *doc_TagSec = "TagSection(text: str, [bytes: bool = False])\n\n" + "Provide methods to access RFC822-style header sections, like those\n" + "found in debian/control or Packages files.\n\n" + "TagSection() behave like read-only dictionaries and also provide access\n" + "to the functions provided by the C++ class (e.g. find).\n\n" + "By default, text read from files is treated as strings (binary data in\n" + "Python 2, Unicode strings in Python 3). Use bytes=True to cause all\n" + "header values read from this TagSection to be bytes even in Python 3.\n" + "Header names are always treated as Unicode."; +PyTypeObject PyTagSection_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.TagSection", // tp_name + sizeof(TagSecData), // tp_basicsize + 0, // tp_itemsize + // Methods + TagSecFree, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + &TagSecSeqMeth, // tp_as_sequence + &TagSecMapMeth, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + TagSecStr, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC), + doc_TagSec, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + TagSecMethods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + TagSecNew, // tp_new +}; + +// Method table for the Tag File object +static PyMethodDef TagFileMethods[] = +{ + // Query + {"step",TagFileStep,METH_VARARGS,doc_Step}, + {"offset",TagFileOffset,METH_VARARGS,doc_Offset}, + {"jump",TagFileJump,METH_VARARGS,doc_Jump}, + {"close",TagFileClose,METH_VARARGS,doc_Close}, + {"__enter__",TagFileEnter,METH_VARARGS,"Context manager entry, return self."}, + {"__exit__",TagFileExit,METH_VARARGS,"Context manager exit, calls close."}, + + {} +}; + +// Return the current section. +static PyObject *TagFileGetSection(PyObject *Self,void*) { + PyObject *Obj = ((TagFileData *)Self)->Section; + Py_INCREF(Obj); + return Obj; +} + +static PyGetSetDef TagFileGetSet[] = { + {"section",TagFileGetSection,0, + "The current section, as a TagSection object.",0}, + {} +}; + + +static char *doc_TagFile = "TagFile(file, [bytes: bool = False])\n\n" + "TagFile() objects provide access to debian control files, which consist\n" + "of multiple RFC822-style sections.\n\n" + "To provide access to those sections, TagFile objects provide an iterator\n" + "which yields TagSection objects for each section.\n\n" + "TagFile objects also provide another API which uses a shared TagSection\n" + "object in the 'section' member. The functions step() and jump() can be\n" + "used to navigate within the file; offset() returns the current\n" + "position.\n\n" + "It is important to not mix the use of both APIs, because this can have\n" + "unwanted effects.\n\n" + "The parameter 'file' refers to an object providing a fileno() method or\n" + "a file descriptor (an integer).\n\n" + "By default, text read from files is treated as strings (binary data in\n" + "Python 2, Unicode strings in Python 3). Use bytes=True to cause all\n" + "header values read from this TagFile to be bytes even in Python 3.\n" + "Header names are always treated as Unicode."; + +// Type for a Tag File +PyTypeObject PyTagFile_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.TagFile", // tp_name + sizeof(TagFileData), // tp_basicsize + 0, // tp_itemsize + // Methods + TagFileFree, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + _PyAptObject_getattro, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_BASETYPE | + Py_TPFLAGS_HAVE_GC), + doc_TagFile, // tp_doc + TagFileTraverse, // tp_traverse + TagFileClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + TagFileIter, // tp_iter + TagFileNext, // tp_iternext + TagFileMethods, // tp_methods + 0, // tp_members + TagFileGetSet, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + TagFileNew, // tp_new + +}; + + +// Return the current section. +static PyObject *TagGetAction(PyObject *Self,void*) { + return MkPyNumber(GetCpp(Self).Action); +} + +static PyObject *TagGetName(PyObject *Self,void*) { + return CppPyString(GetCpp(Self).Name); +} + +static PyObject *TagGetData(PyObject *Self,void*) { + return CppPyString(GetCpp(Self).Data); +} + +static PyObject *PyTagRename_New(PyTypeObject *type,PyObject *Args,PyObject *kwds) { + char *oldName; + char *newName; + char *kwlist[] = {"old_name", "new_name", 0}; + + if (PyArg_ParseTupleAndKeywords(Args,kwds,"ss",kwlist, &oldName, &newName) == 0) + return nullptr; + if (oldName[0] == '\0') { + PyErr_SetString(PyExc_ValueError, "Old tag name may not be empty."); + return nullptr; + } + if (newName[0] == '\0') { + PyErr_SetString(PyExc_ValueError, "New tag name may not be empty."); + return nullptr; + } + + auto tag = pkgTagSection::Tag::Rename(oldName, newName); + return CppPyObject_NEW(nullptr, type, tag); +} + +static PyObject *PyTagRewrite_New(PyTypeObject *type,PyObject *Args,PyObject *kwds) { + char *name; + char *data; + char *kwlist[] = {"name", "data", 0}; + + if (PyArg_ParseTupleAndKeywords(Args,kwds,"ss",kwlist, &name, &data) == 0) + return nullptr; + if (name[0] == '\0') { + PyErr_SetString(PyExc_ValueError, "Tag name may not be empty."); + return nullptr; + } + if (data[0] == '\0') { + PyErr_SetString(PyExc_ValueError, "New value may not be empty."); + return nullptr; + } + + auto tag = pkgTagSection::Tag::Rewrite(name, data); + return CppPyObject_NEW(nullptr, type, tag); +} + +static PyObject *PyTagRemove_New(PyTypeObject *type,PyObject *Args,PyObject *kwds) { + char *name; + char *kwlist[] = {"name", nullptr}; + + if (PyArg_ParseTupleAndKeywords(Args,kwds,"s",kwlist, &name) == 0) + return nullptr; + if (name[0] == '\0') { + PyErr_SetString(PyExc_ValueError, "Tag name may not be empty."); + return nullptr; + } + + auto tag = pkgTagSection::Tag::Remove(name); + return CppPyObject_NEW(nullptr, type, tag); +} + +static PyGetSetDef TagGetSet[] = { + {"action",TagGetAction,0, + "The action to perform.",0}, + {"name",TagGetName,0, + "The name of the tag to perform the action on.",0}, + {"data",TagGetData,0, + "The data to write instead (for REWRITE), or the new tag name (RENAME)",0}, + {} +}; + +static char doc_Tag[] = "Tag\n\n" + "Identify actions to be executed on a task\n" + "\n" + "This is used in conjunction with :meth:`TagSection.write` to rewrite\n" + "a tag section into a new one.\n" + "\n" + "This class is abstract, use one of the subclasses:\n" + ":class:`TagRewrite`, :class:`TagRemove`, :class:`TagRename`\n" + "\n" + ".. versionadded:: 1.1"; + +static char doc_TagRewrite[] = "TagRewrite(name: str, data: str)\n\n" + "Change the value of the tag to the string passed in *data*\n" + "\n" + ".. versionadded:: 1.1"; +static char doc_TagRename[] = "TagRename(old_name: str, new_name: str)\n\n" + "Rename the tag *old_name* to *new_name*\n" + "\n" + ".. versionadded:: 1.1"; + +static char doc_TagRemove[] = "TagRemove(name: str)\n\n" + "Remove the tag *name* from the tag section\n" + "\n" + ".. versionadded:: 1.1"; + + +// Type for a Tag File +PyTypeObject PyTag_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.Tag", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + (Py_TPFLAGS_DEFAULT // tp_flags + | Py_TPFLAGS_BASETYPE), + doc_Tag, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + TagGetSet, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + 0, // tp_new +}; + +// Type for a Tag File +PyTypeObject PyTagRewrite_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.TagRewrite", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + doc_TagRewrite, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + 0, // tp_getset + &PyTag_Type, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PyTagRewrite_New, // tp_new +}; + +// Type for a Tag File +PyTypeObject PyTagRemove_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.TagRemove", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + doc_TagRemove, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + 0, // tp_getset + &PyTag_Type, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PyTagRemove_New, // tp_new +}; + +// Type for a Tag File +PyTypeObject PyTagRename_Type = +{ + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_pkg.TagRename", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + 0, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT, // tp_flags + doc_TagRename, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + 0, // tp_methods + 0, // tp_members + 0, // tp_getset + &PyTag_Type, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + PyTagRename_New, // tp_new +}; diff --git a/python/tarfile.cc b/python/tarfile.cc new file mode 100644 index 0000000..b87fa71 --- /dev/null +++ b/python/tarfile.cc @@ -0,0 +1,521 @@ +/* + * arfile.cc - Wrapper around ExtractTar which behaves like Python's tarfile. + * + * Copyright 2009 Julian Andres Klode + * + * 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., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "generic.h" +#include "apt_instmodule.h" +#include +#include +#include + +/** + * A subclass of pkgDirStream which calls a Python callback. + * + * This calls a Python callback in FinishedFile() with the Item as the first + * argument and the data as the second argument. + * + * It can also work without a callback, in which case it just sets the + * 'py_member' and 'py_data' members. This can be combined with setting + * 'member' to extract a single member into the memory. + */ +class PyDirStream : public pkgDirStream +{ + +public: + PyObject *callback; + PyObject *py_data; + // The requested member or NULL. + const char *member; + // Set to true if an error occurred in the Python callback, or a file + // was too large to read in extractdata. + bool error; + // Place where the copy of the data is stored. + char *copy; + // The size of the copy + size_t copy_size; + + virtual bool DoItem(Item &Itm,int &Fd); + virtual bool FinishedFile(Item &Itm,int Fd); +#if (APT_PKG_MAJOR >= 5) + virtual bool Process(Item &Itm,const unsigned char *Data, + unsigned long long Size,unsigned long long Pos); +#else + virtual bool Process(Item &Itm,const unsigned char *Data, + unsigned long Size,unsigned long Pos); +#endif + PyDirStream(PyObject *callback, const char *member=0) : callback(callback), + py_data(0), member(member), error(false), copy(0), copy_size(0) + { + Py_XINCREF(callback); + } + + virtual ~PyDirStream() { + Py_XDECREF(callback); + Py_XDECREF(py_data); + delete[] copy; + } +}; + +bool PyDirStream::DoItem(Item &Itm, int &Fd) +{ + if (!member || strcmp(Itm.Name, member) == 0) { + // Allocate a new buffer if the old one is too small. + if (Itm.Size > SIZE_MAX) + goto to_large; + if (copy == NULL || copy_size < Itm.Size) { + delete[] copy; + copy = new (std::nothrow) char[Itm.Size]; + if (copy == NULL) + goto to_large; + copy_size = Itm.Size; + } + Fd = -2; + } else { + Fd = -1; + } + return true; +to_large: + delete[] copy; + copy = NULL; + copy_size = 0; + /* If we are looking for a specific member, abort reading now */ + if (member) { + error = true; + PyErr_Format(PyExc_MemoryError, + "The member %s was too large to read into memory", + Itm.Name); + return false; + } + return true; +} + +#if (APT_PKG_MAJOR >= 5) +bool PyDirStream::Process(Item &Itm,const unsigned char *Data, + unsigned long long Size,unsigned long long Pos) +#else +bool PyDirStream::Process(Item &Itm,const unsigned char *Data, + unsigned long Size,unsigned long Pos) +#endif +{ + if (copy != NULL) + memcpy(copy + Pos, Data,Size); + return true; +} + +bool PyDirStream::FinishedFile(Item &Itm,int Fd) +{ + if (member && strcmp(Itm.Name, member) != 0) + // Skip non-matching Items, if a specific one is requested. + return true; + + Py_XDECREF(py_data); + if (copy == NULL) { + Py_INCREF(Py_None); + py_data = Py_None; + } else { + py_data = PyBytes_FromStringAndSize(copy, Itm.Size); + } + + if (!callback) + return true; + + // The current member and data. + CppPyObject *py_member; + py_member = CppPyObject_NEW(0, &PyTarMember_Type); + // Clone our object, including the strings in it. + py_member->Object = Itm; + py_member->Object.Name = new char[strlen(Itm.Name)+1]; + py_member->Object.LinkTarget = new char[strlen(Itm.LinkTarget)+1]; + strcpy(py_member->Object.Name, Itm.Name); + strcpy(py_member->Object.LinkTarget,Itm.LinkTarget); + py_member->NoDelete = true; + error = PyObject_CallFunctionObjArgs(callback, py_member, py_data, 0) == 0; + // Clear the old objects and create new ones. + Py_XDECREF(py_member); + return (!error); +} + +void tarmember_dealloc(PyObject *self) { + // We cloned those strings, delete them again. + delete[] GetCpp(self).Name; + delete[] GetCpp(self).LinkTarget; + CppDealloc(self); +} + +// The tarfile.TarInfo interface for our TarMember class. +static PyObject *tarmember_isblk(PyObject *self, PyObject *args) +{ + return PyBool_FromLong(GetCpp(self).Type == + pkgDirStream::Item::BlockDevice); +} +static PyObject *tarmember_ischr(PyObject *self, PyObject *args) +{ + return PyBool_FromLong(GetCpp(self).Type == + pkgDirStream::Item::CharDevice); +} +static PyObject *tarmember_isdev(PyObject *self, PyObject *args) +{ + pkgDirStream::Item::Type_t type = GetCpp(self).Type; + return PyBool_FromLong(type == pkgDirStream::Item::CharDevice || + type == pkgDirStream::Item::BlockDevice || + type == pkgDirStream::Item::FIFO); +} + +static PyObject *tarmember_isdir(PyObject *self, PyObject *args) +{ + return PyBool_FromLong(GetCpp(self).Type == + pkgDirStream::Item::Directory); +} + +static PyObject *tarmember_isfifo(PyObject *self, PyObject *args) +{ + return PyBool_FromLong(GetCpp(self).Type == + pkgDirStream::Item::FIFO); +} + +static PyObject *tarmember_isfile(PyObject *self, PyObject *args) +{ + return PyBool_FromLong(GetCpp(self).Type == + pkgDirStream::Item::File); +} +static PyObject *tarmember_islnk(PyObject *self, PyObject *args) +{ + return PyBool_FromLong(GetCpp(self).Type == + pkgDirStream::Item::HardLink); +} +static PyObject *tarmember_isreg(PyObject *self, PyObject *args) +{ + return tarmember_isfile(self, NULL); +} +static PyObject *tarmember_issym(PyObject *self, PyObject *args) +{ + return PyBool_FromLong(GetCpp(self).Type == + pkgDirStream::Item::SymbolicLink); +} + +static PyObject *tarmember_get_name(PyObject *self, void *closure) +{ + return CppPyPath(GetCpp(self).Name); +} + +static PyObject *tarmember_get_linkname(PyObject *self, void *closure) +{ + return CppPyPath(GetCpp(self).LinkTarget); +} + +static PyObject *tarmember_get_mode(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self).Mode); +} + +static PyObject *tarmember_get_uid(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self).UID); +} +static PyObject *tarmember_get_gid(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self).GID); +} +static PyObject *tarmember_get_size(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self).Size); +} + +static PyObject *tarmember_get_mtime(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self).MTime); +} + +static PyObject *tarmember_get_major(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self).Major); +} + +static PyObject *tarmember_get_minor(PyObject *self, void *closure) +{ + return MkPyNumber(GetCpp(self).Minor); +} + +static PyObject *tarmember_repr(PyObject *self) +{ + return PyString_FromFormat("<%s object: name:'%s'>", + self->ob_type->tp_name, + GetCpp(self).Name); + +} + + +static PyMethodDef tarmember_methods[] = { + {"isblk",tarmember_isblk,METH_NOARGS, + "Determine whether the member is a block device."}, + {"ischr",tarmember_ischr,METH_NOARGS, + "Determine whether the member is a character device."}, + {"isdev",tarmember_isdev,METH_NOARGS, + "Determine whether the member is a device (block, character or FIFO)."}, + {"isdir",tarmember_isdir,METH_NOARGS, + "Determine whether the member is a directory."}, + {"isfifo",tarmember_isfifo,METH_NOARGS, + "Determine whether the member is a FIFO."}, + {"isfile",tarmember_isfile,METH_NOARGS, + "Determine whether the member is a regular file."}, + {"islnk",tarmember_islnk,METH_NOARGS, + "Determine whether the member is a hardlink."}, + {"isreg",tarmember_isreg,METH_NOARGS, + "Determine whether the member is a regular file, same as isfile()."}, + {"issym",tarmember_issym,METH_NOARGS, + "Determine whether the member is a symbolic link."}, + {NULL} +}; + +static PyGetSetDef tarmember_getset[] = { + {"gid",tarmember_get_gid,0,"The owner's group ID."}, + {"linkname",tarmember_get_linkname,0,"The target of the link."}, + {"major",tarmember_get_major,0,"The major ID of the device."}, + {"minor",tarmember_get_minor,0,"The minor ID of the device."}, + {"mode",tarmember_get_mode,0,"The mode (permissions)."}, + {"mtime",tarmember_get_mtime,0,"Last time of modification."}, + {"name",tarmember_get_name,0,"The name of the file."}, + {"size",tarmember_get_size,0,"The size of the file."}, + {"uid",tarmember_get_uid,0,"The owner's user ID."}, + {NULL} +}; + +static const char *tarmember_doc = + "Represent a single member of a 'tar' archive.\n\n" + "This class, which has been modelled after 'tarfile.TarInfo', represents\n" + "information about a given member in an archive."; +PyTypeObject PyTarMember_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_inst.TarMember", // tp_name + sizeof(CppPyObject), // tp_basicsize + 0, // tp_itemsize + // Methods + tarmember_dealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + tarmember_repr, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_HAVE_GC, + tarmember_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + tarmember_methods, // tp_methods + 0, // tp_members + tarmember_getset // tp_getset +}; + + + +static PyObject *tarfile_new(PyTypeObject *type,PyObject *args,PyObject *kwds) +{ + PyObject *file; + PyApt_Filename filename; + int fileno; + int min = 0; + int max = 0xFFFFFFFF; + char *comp = "gzip"; + + static char *kwlist[] = {"file","min","max","comp",NULL}; + if (PyArg_ParseTupleAndKeywords(args, kwds, "O|iis", kwlist, &file, &min, + &max,&comp) == 0) + return 0; + + PyApt_UniqueObject self((PyTarFileObject*)CppPyObject_NEW(file,type)); + + // We receive a filename. + if (filename.init(file)) + new (&self->Fd) FileFd((const char *) filename,FileFd::ReadOnly); + else if ((fileno = PyObject_AsFileDescriptor(file)) != -1) { + // clear the error set by PyObject_AsString(). + PyErr_Clear(); + new (&self->Fd) FileFd(fileno,false); + } + else { + return 0; + } + + self->min = min; + self->Object = new ExtractTar(self->Fd,max,comp); + if (_error->PendingError() == true) + return HandleErrors(self.release()); + return self.release(); +} + +static const char *tarfile_extractall_doc = + "extractall([rootdir: str]) -> True\n\n" + "Extract the archive in the current directory. The argument 'rootdir'\n" + "can be used to change the target directory."; +static PyObject *tarfile_extractall(PyObject *self, PyObject *args) +{ + std::string cwd = SafeGetCWD(); + PyApt_Filename rootdir; + if (PyArg_ParseTuple(args,"|O&:extractall", PyApt_Filename::Converter, &rootdir) == 0) + return 0; + + if (rootdir) { + if (chdir(rootdir) == -1) + return PyErr_SetFromErrnoWithFilename(PyExc_OSError, rootdir); + } + + pkgDirStream Extract; + + ((PyTarFileObject*)self)->Fd.Seek(((PyTarFileObject*)self)->min); + bool res = GetCpp(self)->Go(Extract); + + + + if (rootdir) { + if (chdir(cwd.c_str()) == -1) + return PyErr_SetFromErrnoWithFilename(PyExc_OSError, + (char*)cwd.c_str()); + } + return HandleErrors(PyBool_FromLong(res)); +} + +static const char *tarfile_go_doc = + "go(callback: callable[, member: str]) -> True\n\n" + "Go through the archive and call the callable 'callback' for each\n" + "member with 2 arguments. The first argument is the TarMember and\n" + "the second one is the data, as bytes.\n\n" + "The optional parameter 'member' can be used to specify the member for\n" + "which to call the callback. If not specified, it will be called for all\n" + "members. If specified and not found, LookupError will be raised."; +static PyObject *tarfile_go(PyObject *self, PyObject *args) +{ + PyObject *callback; + PyApt_Filename member; + if (PyArg_ParseTuple(args,"O|O&",&callback, PyApt_Filename::Converter, &member) == 0) + return 0; + if (member && strcmp(member, "") == 0) + member = 0; + pkgDirStream Extract; + PyDirStream stream(callback, member); + ((PyTarFileObject*)self)->Fd.Seek(((PyTarFileObject*)self)->min); + bool res = GetCpp(self)->Go(stream); + if (stream.error) + return 0; + if (member && !stream.py_data) + return PyErr_Format(PyExc_LookupError, "There is no member named '%s'", + member.path); + return HandleErrors(PyBool_FromLong(res)); +} + +static const char *tarfile_extractdata_doc = + "extractdata(member: str) -> bytes\n\n" + "Return the contents of the member, as a bytes object. Raise\n" + "LookupError if there is no member with the given name."; +static PyObject *tarfile_extractdata(PyObject *self, PyObject *args) +{ + PyApt_Filename member; + if (PyArg_ParseTuple(args,"O&", PyApt_Filename::Converter, &member) == 0) + return 0; + PyDirStream stream(NULL, member); + ((PyTarFileObject*)self)->Fd.Seek(((PyTarFileObject*)self)->min); + // Go through the stream. + GetCpp(self)->Go(stream); + + if (stream.error) + return 0; + + if (!stream.py_data) + return PyErr_Format(PyExc_LookupError, "There is no member named '%s'", + member.path); + return Py_INCREF(stream.py_data), stream.py_data; +} + +static PyMethodDef tarfile_methods[] = { + {"extractdata",tarfile_extractdata,METH_VARARGS,tarfile_extractdata_doc}, + {"extractall",tarfile_extractall,METH_VARARGS,tarfile_extractall_doc}, + {"go",tarfile_go,METH_VARARGS,tarfile_go_doc}, + {NULL} +}; + +static PyObject *tarfile_repr(PyObject *self) +{ + return PyString_FromFormat("<%s object: %s>", self->ob_type->tp_name, + PyString_AsString(PyObject_Repr(GetOwner(self)))); +} + +static const char *tarfile_doc = + "TarFile(file: str/int/file[, min: int, max: int, comp: str])\n\n" + "The parameter 'file' may be a string specifying the path of a file, or\n" + "a file-like object providing the fileno() method. It may also be an int\n" + "specifying a file descriptor (returned by e.g. os.open()).\n\n" + "The parameter 'min' describes the offset in the file where the archive\n" + "begins and the parameter 'max' is the size of the archive.\n\n" + "The compression of the archive is set by the parameter 'comp'. It can\n" + "be set to any program supporting the -d switch, the default being gzip."; +PyTypeObject PyTarFile_Type = { + PyVarObject_HEAD_INIT(&PyType_Type, 0) + "apt_inst.TarFile", // tp_name + sizeof(PyTarFileObject), // tp_basicsize + 0, // tp_itemsize + // Methods + CppDealloc, // tp_dealloc + 0, // tp_print + 0, // tp_getattr + 0, // tp_setattr + 0, // tp_compare + tarfile_repr, // tp_repr + 0, // tp_as_number + 0, // tp_as_sequence + 0, // tp_as_mapping + 0, // tp_hash + 0, // tp_call + 0, // tp_str + 0, // tp_getattro + 0, // tp_setattro + 0, // tp_as_buffer + Py_TPFLAGS_DEFAULT | // tp_flags + Py_TPFLAGS_HAVE_GC, + tarfile_doc, // tp_doc + CppTraverse, // tp_traverse + CppClear, // tp_clear + 0, // tp_richcompare + 0, // tp_weaklistoffset + 0, // tp_iter + 0, // tp_iternext + tarfile_methods, // tp_methods + 0, // tp_members + 0, // tp_getset + 0, // tp_base + 0, // tp_dict + 0, // tp_descr_get + 0, // tp_descr_set + 0, // tp_dictoffset + 0, // tp_init + 0, // tp_alloc + tarfile_new // tp_new +}; diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..c0c0440 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,5 @@ +[build_l10n] +domain=python-apt + +[sdist] +formats = bztar diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..522de24 --- /dev/null +++ b/setup.py @@ -0,0 +1,159 @@ +#!/usr/bin/python3 +# Builds on python2.X and python3 +# $Id: setup.py,v 1.2 2002/01/08 07:13:21 jgg Exp $ +import glob +import os +import shutil +import subprocess +import sys + +from setuptools import Extension, setup +from setuptools.command.install import install + +cmdclass = {} + +try: + from DistUtilsExtra.auto import clean_build_tree + from DistUtilsExtra.command import build_extra, build_i18n +except ImportError: + print("W: [python%s] DistUtilsExtra import error." % sys.version[:3]) +else: + cmdclass["build"] = build_extra.build_extra + cmdclass["build_i18n"] = build_i18n.build_i18n + cmdclass["clean"] = clean_build_tree + + +class InstallTypeinfo(install): + def run(self): + install.run(self) + for pyi in glob.glob("typehinting/*.pyi"): + stubs = os.path.basename(pyi).split(".")[0] + "-stubs" + stubs = os.path.join(self.install_purelib, stubs) + if not os.path.exists(stubs): + os.makedirs(stubs) + shutil.copy(pyi, os.path.join(stubs, "__init__.pyi")) + + +cmdclass["install"] = InstallTypeinfo + + +def get_version(): + """Get a PEP 0440 compatible version string""" + version = os.environ.get("DEBVER") + if not version: + proc = subprocess.Popen( + ["dpkg-parsechangelog", "-SVersion"], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + ) + out, _ = proc.communicate() + if proc.returncode == 0: + version = out.decode("utf-8") + + version = version.strip() + + if not version: + return version + + version = version.replace("~alpha", ".a") + version = version.replace("~beta", ".b") + version = version.replace("~rc", ".rc") + version = version.replace("~exp", ".dev") + version = version.replace("ubuntu", "+ubuntu") + version = version.replace("tanglu", "+tanglu") + version = version.split("build")[0] + + return version + + +# The apt_pkg module. +files = [ + "apt_pkgmodule.cc", + "acquire.cc", + "cache.cc", + "cdrom.cc", + "configuration.cc", + "depcache.cc", + "generic.cc", + "hashes.cc", + "hashstring.cc", + "indexfile.cc", + "metaindex.cc", + "pkgmanager.cc", + "pkgrecords.cc", + "pkgsrcrecords.cc", + "policy.cc", + "progress.cc", + "sourcelist.cc", + "string.cc", + "tag.cc", + "lock.cc", + "acquire-item.cc", + "python-apt-helpers.cc", + "cachegroup.cc", + "orderlist.cc", + "hashstringlist.cc", +] +files = sorted(["python/" + fname for fname in files], key=lambda s: s[:-3]) +apt_pkg = Extension( + "apt_pkg", + files, + libraries=["apt-pkg"], + extra_compile_args=[ + "-std=c++11", + "-Wno-write-strings", + "-DAPT_8_CLEANER_HEADERS", + "-DAPT_9_CLEANER_HEADERS", + "-DAPT_10_CLEANER_HEADERS", + "-DPY_SSIZE_T_CLEAN", + ], +) + +# The apt_inst module +files = [ + "python/apt_instmodule.cc", + "python/generic.cc", + "python/arfile.cc", + "python/tarfile.cc", +] +apt_inst = Extension( + "apt_inst", + files, + libraries=["apt-pkg"], + extra_compile_args=["-std=c++11", "-Wno-write-strings", "-DPY_SSIZE_T_CLEAN"], +) + +# Replace the leading _ that is used in the templates for translation +if len(sys.argv) > 1 and sys.argv[1] == "build": + if not os.path.exists("build/data/templates/"): + os.makedirs("build/data/templates") + for template in glob.glob("data/templates/*.info.in"): + source = open(template) + build = open("build/" + template[:-3], "w") + for line in source: + build.write(line.lstrip("_")) + source.close() + build.close() + for template in glob.glob("data/templates/*.mirrors"): + shutil.copy(template, os.path.join("build", template)) + + +setup( + name="python-apt", + description="Python bindings for APT", + version=get_version(), + author="APT Development Team", + author_email="deity@lists.debian.org", + ext_modules=[apt_pkg, apt_inst], + packages=["apt", "apt.progress", "aptsources"], + package_data={ + "apt": ["*.pyi", "py.typed"], + }, + data_files=[ + ("share/python-apt/templates", glob.glob("build/data/templates/*.info")), + ("share/python-apt/templates", glob.glob("data/templates/*.mirrors")), + ], + cmdclass=cmdclass, + license="GNU GPL", + platforms="posix", +) diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..792d600 --- /dev/null +++ b/tests/__init__.py @@ -0,0 +1 @@ +# diff --git a/tests/data/aptsources/lsb-release b/tests/data/aptsources/lsb-release new file mode 100644 index 0000000..c4b5944 --- /dev/null +++ b/tests/data/aptsources/lsb-release @@ -0,0 +1,4 @@ +DISTRIB_ID=Ubuntu +DISTRIB_RELEASE=16.04 +DISTRIB_CODENAME=xenial +DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS" diff --git a/tests/data/aptsources/os-release b/tests/data/aptsources/os-release new file mode 100644 index 0000000..95a5bcd --- /dev/null +++ b/tests/data/aptsources/os-release @@ -0,0 +1,10 @@ +NAME="KDE neon" +VERSION="16.04 LTS" +ID=neon +ID_LIKE="ubuntu debian" +PRETTY_NAME="KDE neon User Edition on 16.04 LTS" +VERSION_ID="16.04" +HOME_URL="http://neon.kde.org/" +SUPPORT_URL="http://neon.kde.org/" +BUG_REPORT_URL="http://bugs.kde.org/" +UBUNTU_CODENAME=xenial diff --git a/tests/data/aptsources/sources.list b/tests/data/aptsources/sources.list new file mode 100644 index 0000000..8ca6807 --- /dev/null +++ b/tests/data/aptsources/sources.list @@ -0,0 +1,10 @@ +# comment 1 +deb http://de.archive.ubuntu.com/ubuntu/ edgy main +# comment 2 +deb http://de.archive.ubuntu.com/ubuntu/ edgy restricted +# comment 3 +deb http://de.archive.ubuntu.com/ubuntu/ edgy universe + +# multi-arch +deb [arch=amd64,i386] http://de.archive.ubuntu.com/ubuntu/ natty main +deb [arch=amd64,i386 trusted=yes] http://de.archive.ubuntu.com/ubuntu/ natty main diff --git a/tests/data/aptsources/sources.list.d.testDistribution/main.sources b/tests/data/aptsources/sources.list.d.testDistribution/main.sources new file mode 100644 index 0000000..ccdda20 --- /dev/null +++ b/tests/data/aptsources/sources.list.d.testDistribution/main.sources @@ -0,0 +1,74 @@ +Types: deb +URIs: http://de.archive.ubuntu.com/ubuntu/ +Suites: hardy +Components: main + +Types: deb +URIs: http://de.archive.ubuntu.com/ubuntu/ +Suites: hardy +Components: restricted + +Types: deb +URIs: http://de.archive.ubuntu.com/ubuntu/ +Suites: hardy +Components: universe + +Types: deb +URIs: http://de.archive.ubuntu.com/ubuntu/ +Suites: hardy-updates +Components: universe multiverse + +Types: deb +URIs: http://de.archive.ubuntu.com/ubuntu/ +Suites: hardy-updates +Components: restricted + +Types: deb +URIs: http://de.archive.ubuntu.com/ubuntu/ +Suites: hardy-security +Components: main + +Types: deb +URIs: http://de.archive.ubuntu.com/ubuntu/ +Suites: hardy-security +Components: multiverse + +Types: deb +URIs: http://de.archive.ubuntu.com/ubuntu/ +Suites: hardy-security +Components: multiverse + +Types: deb +URIs: http://ftp.debian.org/debian +Suites: sid +Components: main + +Types: deb +URIs: http://archive.tanglu.org/tanglu +Suites: aequorea +Components: main + +Types: deb +URIs: http://ftp.hosteurope.de/mirror/archive.ubuntu.com/ +Suites: hardy +Components: main + +Types: deb +URIs: http://ftp.hosteurope.de/mirror/archive.ubuntu.com/ +Suites: hardy-backports +Components: main + +Types: deb +URIs: http://archive.ubuntu.com/ubuntu/ +Suites: intrepid +Components: main + +Types: deb +URIs: cdrom:[Ubuntu 8.10 _Intrepid Ibex_ - Alpha]/ +Suites: intrepid +Components: main + +Types: deb +URIs: cdrom:[Ubuntu 8.04 _Hardy Heron_] +Suites: hardy +Components: main diff --git a/tests/data/aptsources/sources.list.d.testDuplication/main.sources b/tests/data/aptsources/sources.list.d.testDuplication/main.sources new file mode 100644 index 0000000..5b7765b --- /dev/null +++ b/tests/data/aptsources/sources.list.d.testDuplication/main.sources @@ -0,0 +1,10 @@ +Types: deb +URIs: http://ppa.launchpad.net/me/myproject/ubuntu +Suites: xenial +Components: main + +Types: deb-src +URIs: http://ppa.launchpad.net/me/myproject/ubuntu +Suites: xenial +Components: main +Enabled: no diff --git a/tests/data/aptsources/sources.list.d/main.sources b/tests/data/aptsources/sources.list.d/main.sources new file mode 100644 index 0000000..2495f06 --- /dev/null +++ b/tests/data/aptsources/sources.list.d/main.sources @@ -0,0 +1,32 @@ +# comment 1 +# note that we have deliberate case typos in each paragraph to test case-insensitivity +TyPes: deb +URIs: http://de.archive.ubuntu.com/ubuntu/ +Suites: edgy +Components: main + +# comment 2 +Types: deb +uRIs: http://de.archive.ubuntu.com/ubuntu/ +Suites: edgy +Components: restricted + +# comment 3 +Types: deb +URIs: http://de.archive.ubuntu.com/ubuntu/ +SuiTes: edgy +Components: universe + +# multi-arch +Types: deb +URIs: http://de.archive.ubuntu.com/ubuntu/ +Suites: natty +ComPonents: main +Architectures: amd64 i386 + +Types: deb +URIs: http://de.archive.ubuntu.com/ubuntu/ +Suites: natty +Components: main +ArchiTectures: amd64 i386 +Trusted: yes diff --git a/tests/data/aptsources/sources.list.testDistribution b/tests/data/aptsources/sources.list.testDistribution new file mode 100644 index 0000000..021ee87 --- /dev/null +++ b/tests/data/aptsources/sources.list.testDistribution @@ -0,0 +1,14 @@ +deb http://de.archive.ubuntu.com/ubuntu/ hardy main +deb http://de.archive.ubuntu.com/ubuntu/ hardy restricted +deb http://de.archive.ubuntu.com/ubuntu/ hardy universe +deb http://de.archive.ubuntu.com/ubuntu/ hardy-updates universe multiverse +deb http://de.archive.ubuntu.com/ubuntu/ hardy-updates restricted +deb http://de.archive.ubuntu.com/ubuntu/ hardy-security main +deb http://de.archive.ubuntu.com/ubuntu/ hardy-security multiverse +deb http://ftp.debian.org/debian sid main +deb http://archive.tanglu.org/tanglu aequorea main +deb http://ftp.hosteurope.de/mirror/archive.ubuntu.com/ hardy main +deb http://ftp.hosteurope.de/mirror/archive.ubuntu.com/ hardy-backports main +deb http://archive.ubuntu.com/ubuntu/ intrepid main +deb cdrom:[Ubuntu 8.10 _Intrepid Ibex_ - Alpha]/ intrepid main +deb cdrom:[Ubuntu 8.04 _Hardy Heron_] hardy main diff --git a/tests/data/aptsources/sources.list.testDuplication b/tests/data/aptsources/sources.list.testDuplication new file mode 100644 index 0000000..28a4db2 --- /dev/null +++ b/tests/data/aptsources/sources.list.testDuplication @@ -0,0 +1,2 @@ +deb http://ppa.launchpad.net/me/myproject/ubuntu xenial main +# deb-src http://ppa.launchpad.net/me/myproject/ubuntu xenial main diff --git a/tests/data/aptsources_ports/sources.list b/tests/data/aptsources_ports/sources.list new file mode 100644 index 0000000..0efa282 --- /dev/null +++ b/tests/data/aptsources_ports/sources.list @@ -0,0 +1,52 @@ +# +# deb cdrom:[Ubuntu-Server 8.04.1 _Hardy Heron_ - Release powerpc (20080703)]/ hardy main restricted + +# deb cdrom:[Ubuntu-Server 8.04.1 _Hardy Heron_ - Release powerpc (20080703)]/ hardy main restricted +# See http://help.ubuntu.com/community/UpgradeNotes for how to upgrade to +# newer versions of the distribution. + +deb http://ports.ubuntu.com/ubuntu-ports/ hardy main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ hardy main restricted + +## Major bug fix updates produced after the final release of the +## distribution. +deb http://ports.ubuntu.com/ubuntu-ports/ hardy-updates main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ hardy-updates main restricted + +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu +## team, and may not be under a free licence. Please satisfy yourself as to +## your rights to use the software. Also, please note that software in +## universe WILL NOT receive any review or updates from the Ubuntu security +## team. +deb http://ports.ubuntu.com/ubuntu-ports/ hardy universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ hardy universe +deb http://ports.ubuntu.com/ubuntu-ports/ hardy-updates universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ hardy-updates universe + +## N.B. software from this repository is ENTIRELY UNSUPPORTED by the Ubuntu +## team, and may not be under a free licence. Please satisfy yourself as to +## your rights to use the software. Also, please note that software in +## multiverse WILL NOT receive any review or updates from the Ubuntu +## security team. +deb http://ports.ubuntu.com/ubuntu-ports/ hardy multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ hardy multiverse +deb http://ports.ubuntu.com/ubuntu-ports/ hardy-updates multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ hardy-updates multiverse + +## Uncomment the following two lines to add software from the 'backports' +## repository. +## N.B. software from this repository may not have been tested as +## extensively as that contained in the main release, although it includes +## newer versions of some applications which may provide useful features. +## Also, please note that software in backports WILL NOT receive any review +## or updates from the Ubuntu security team. +# deb http://ports.ubuntu.com/ubuntu-ports/ hardy-backports main restricted universe multiverse +# deb-src http://ports.ubuntu.com/ubuntu-ports/ hardy-backports main restricted universe multiverse + +deb http://ports.ubuntu.com/ubuntu-ports/ hardy-security main restricted +deb-src http://ports.ubuntu.com/ubuntu-ports/ hardy-security main restricted +deb http://ports.ubuntu.com/ubuntu-ports/ hardy-security universe +deb-src http://ports.ubuntu.com/ubuntu-ports/ hardy-security universe +deb http://ports.ubuntu.com/ubuntu-ports/ hardy-security multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ hardy-security multiverse +deb-src http://ports.ubuntu.com/ubuntu-ports/ hardy-proposed restricted main multiverse universe diff --git a/tests/data/fake-packages/Packages b/tests/data/fake-packages/Packages new file mode 100644 index 0000000..9fbab95 --- /dev/null +++ b/tests/data/fake-packages/Packages @@ -0,0 +1,21 @@ +Package: 2vcard +Priority: optional +Section: universe/utils +Installed-Size: 108 +Maintainer: Arvind Autar +Architecture: amd64 +Version: 0.5-1ubuntu1 +Filename: pool/universe/2/2vcard/2vcard_0.5-1ubuntu1_amd64.deb +Size: 14164 +MD5sum: 105ea91f0a75417d0f9e8e9624513b2a +SHA1: d55beee01c08efc33cd131e106330dca72ee14be +SHA256: 4a72edaf87cdb826e5508b85311fcf0bec9b7e019a55740ded7feb1b9e197f11 +Description: A little perl script to convert an adressbook to VCARD file format + 2vcard is a little perl script that you can use to convert the popular vcard + file format. Currently 2vcard can only convert adressbooks and alias files from + the following formats: abook,eudora,juno,ldif,mutt,mh and pine. + . + The VCARD format is used by gnomecard, for example, which is turn is used by + the balsa email client. +Bugs: mailto:ubuntu-users@lists.ubuntu.com +Origin: Ubuntu diff --git a/tests/data/fake-packages/Packages.gz b/tests/data/fake-packages/Packages.gz new file mode 100644 index 0000000..506bc8d Binary files /dev/null and b/tests/data/fake-packages/Packages.gz differ diff --git a/tests/data/hashsums/hashsum_test.data b/tests/data/hashsums/hashsum_test.data new file mode 100644 index 0000000..1910281 --- /dev/null +++ b/tests/data/hashsums/hashsum_test.data @@ -0,0 +1 @@ +foo \ No newline at end of file diff --git a/tests/data/hashsums/hashsum_test_with_zero.data b/tests/data/hashsums/hashsum_test_with_zero.data new file mode 100644 index 0000000..2ec9a6d Binary files /dev/null and b/tests/data/hashsums/hashsum_test_with_zero.data differ diff --git a/tests/data/misc/foo_Release b/tests/data/misc/foo_Release new file mode 100644 index 0000000..0f42220 --- /dev/null +++ b/tests/data/misc/foo_Release @@ -0,0 +1,492 @@ +Origin: Ubuntu +Label: Ubuntu +Suite: precise +Version: 12.04 +Codename: precise +Date: Wed, 25 Apr 2012 22:49:23 UTC +Architectures: amd64 armel armhf i386 powerpc +Components: main restricted universe multiverse +Description: Ubuntu Precise 12.04 +MD5Sum: + 6a815674c5b3178152d449a9396cb2e5 1640344 main/binary-amd64/Packages.gz + 98140fa3444c9e945f6944acbb9ddcff 7818931 main/binary-amd64/Packages + 846e0e856bcbf9b64d9119c8727cda8c 97 main/binary-amd64/Release + cfd5f57de107941bbe661ffada4dce88 1272844 main/binary-amd64/Packages.bz2 + 5b220aea8056a900c8eaf28e79cdd64a 97 main/binary-armel/Release + 92e3160bbb664f8b5d7d4f2d161dd81c 1619078 main/binary-armel/Packages.gz + 28fbf69ee965639c92c8a54256cd6ba1 1257389 main/binary-armel/Packages.bz2 + 4e3ba67129f73f8afe28186b31eb3112 7743353 main/binary-armel/Packages + 81cfd32bf54d2b007542e14e09953bae 97 main/binary-armhf/Release + ed404b1123d1497cb09aceae8850fc06 7620333 main/binary-armhf/Packages + 64156d29df19fdaa36fa4eafd4c17dc1 1257653 main/binary-armhf/Packages.bz2 + 3d3238bd89cb1e8e23a1a4a5bf574739 1617483 main/binary-armhf/Packages.gz + dc2fe62f05e29f36ffe4e58499796ae6 1273857 main/binary-i386/Packages.bz2 + 7c678c50ce682e9f5cc5ba8f8eb2d6ad 1641082 main/binary-i386/Packages.gz + b6aa9a96c765bbd4202dae7dbaf18cc2 96 main/binary-i386/Release + eb3b4870b877863fecf1d3307c3beb54 7816415 main/binary-i386/Packages + 54658d89b612a38592431fe6b8a780a1 1627734 main/binary-powerpc/Packages.gz + 4185aca6984f00fd65aa0c0de12367d4 99 main/binary-powerpc/Release + fc9bf1959082733fc42c682285bf46e7 1263942 main/binary-powerpc/Packages.bz2 + c32afd79c9163cffe013f98669deb727 7661552 main/binary-powerpc/Packages + ff5434612595a569236f7ba4990a3b63 62166 main/debian-installer/binary-amd64/Packages.gz + 7dd470290bacbacc7bec24830100aade 234592 main/debian-installer/binary-amd64/Packages + 013d9839e9c8f8c102daf6eb77841bf7 48784 main/debian-installer/binary-amd64/Packages.bz2 + 08608ef832f2410970d07fdd802fc4e4 47964 main/debian-installer/binary-armel/Packages.bz2 + 0a0a559023aac4096a38e2fb51870ddf 230310 main/debian-installer/binary-armel/Packages + f79f29b841a05b971ac318a9e0a396e0 61118 main/debian-installer/binary-armel/Packages.gz + 20a72276b6607fa58f52fcc5b7742ff4 62777 main/debian-installer/binary-armhf/Packages.gz + 8da4a15400cec4b06e2aa1bba6cfc2c3 49051 main/debian-installer/binary-armhf/Packages.bz2 + 49f9f82a7c7e9e13c399d15df43148f1 238862 main/debian-installer/binary-armhf/Packages + 3dd181be504206f7abb41039dc508ed9 52279 main/debian-installer/binary-i386/Packages.bz2 + 5c2c6ca586bb6ffb2de414e2cd063c70 259996 main/debian-installer/binary-i386/Packages + ca1b7db323ebef593617ef0a7c833dfb 67180 main/debian-installer/binary-i386/Packages.gz + 876f115ee26518319458fc26ec785485 246636 main/debian-installer/binary-powerpc/Packages + 49402b5b12b10804abfae14629d23f1c 50309 main/debian-installer/binary-powerpc/Packages.bz2 + 29010a7ba3ac1e60a0efaef04f6f2e42 64468 main/debian-installer/binary-powerpc/Packages.gz + adf74189a01512a8f68d4bfc411dc692 3706 main/i18n/Index + 2f2ddab9be4ecc2c9e190bb639304943 4356187 main/source/Sources + 5c2893c352ebbf3ee380ebdab6b5e487 933770 main/source/Sources.bz2 + 323e5ca1ba86c7a503c4c7b0772749b1 1174967 main/source/Sources.gz + 3c3104465b2c7e54f4b8f566ac825339 98 main/source/Release + f75f8a98e9e952194046da388a11c42a 119109 multiverse/binary-amd64/Packages.bz2 + c2df9a9ff319486e3d6f46d9c35a8530 151924 multiverse/binary-amd64/Packages.gz + ece719c6a770134150f158cdb65ca6fc 581550 multiverse/binary-amd64/Packages + d3f34ec2fc86c95e4d3bc4606d751c66 103 multiverse/binary-amd64/Release + f296954282382f88b12dd8c64d813f5c 136295 multiverse/binary-armel/Packages.gz + d0da88f8a408fba12d44d5b6e107cfc0 519605 multiverse/binary-armel/Packages + 6d0c32b1cae4bdcfd6f18fd2d6fbf31f 103 multiverse/binary-armel/Release + 6744aaa8a3457d139348ea18379781ce 106873 multiverse/binary-armel/Packages.bz2 + 1cc2613becf46fd578aa6d52ab12db94 104529 multiverse/binary-armhf/Packages.bz2 + b0f8df0c9d700a1f7d295be4d4c03788 505901 multiverse/binary-armhf/Packages + 73cb5bc3d0c5021e5a4a413a73bcefce 103 multiverse/binary-armhf/Release + 00c07f1601226b8387fe4c9afaf2b044 133117 multiverse/binary-armhf/Packages.gz + bf0237c8c5d06a6df172db28710b8a36 121196 multiverse/binary-i386/Packages.bz2 + cf110f58668bf5731e593ed78af54c27 591662 multiverse/binary-i386/Packages + 8a915986a504c0f3eb95b61ae909c9a4 102 multiverse/binary-i386/Release + c6d89a2752d1154a219c295e6d70b697 154762 multiverse/binary-i386/Packages.gz + ae93681c6b316c95207091b3c91042a7 105 multiverse/binary-powerpc/Release + ec463c2070c515de099f8baa3a4b5993 107209 multiverse/binary-powerpc/Packages.bz2 + 675204a2b4aabeb9e99e406070b2af9b 520882 multiverse/binary-powerpc/Packages + c806ea7584c782d57363df12ddb28839 136930 multiverse/binary-powerpc/Packages.gz + d41d8cd98f00b204e9800998ecf8427e 0 multiverse/debian-installer/binary-amd64/Packages + 4a4dd3598707603b3f76a2378a4504aa 20 multiverse/debian-installer/binary-amd64/Packages.gz + 4059d198768f9f8dc9372dc1c54bc3c3 14 multiverse/debian-installer/binary-amd64/Packages.bz2 + 4059d198768f9f8dc9372dc1c54bc3c3 14 multiverse/debian-installer/binary-armel/Packages.bz2 + d41d8cd98f00b204e9800998ecf8427e 0 multiverse/debian-installer/binary-armel/Packages + 4a4dd3598707603b3f76a2378a4504aa 20 multiverse/debian-installer/binary-armel/Packages.gz + 4a4dd3598707603b3f76a2378a4504aa 20 multiverse/debian-installer/binary-armhf/Packages.gz + d41d8cd98f00b204e9800998ecf8427e 0 multiverse/debian-installer/binary-armhf/Packages + 4059d198768f9f8dc9372dc1c54bc3c3 14 multiverse/debian-installer/binary-armhf/Packages.bz2 + 4059d198768f9f8dc9372dc1c54bc3c3 14 multiverse/debian-installer/binary-i386/Packages.bz2 + 4a4dd3598707603b3f76a2378a4504aa 20 multiverse/debian-installer/binary-i386/Packages.gz + d41d8cd98f00b204e9800998ecf8427e 0 multiverse/debian-installer/binary-i386/Packages + 4a4dd3598707603b3f76a2378a4504aa 20 multiverse/debian-installer/binary-powerpc/Packages.gz + d41d8cd98f00b204e9800998ecf8427e 0 multiverse/debian-installer/binary-powerpc/Packages + 4059d198768f9f8dc9372dc1c54bc3c3 14 multiverse/debian-installer/binary-powerpc/Packages.bz2 + a2bcfa86da39328db94629011506a877 2676 multiverse/i18n/Index + c2ffda2a848000b71573dbc3dc7d4402 154990 multiverse/source/Sources.bz2 + f1d64bb88933686a71108de73b1f2262 628753 multiverse/source/Sources + 3d35747578528fa13640b98184120e51 188325 multiverse/source/Sources.gz + c9828946b46ac900fec682369c52bfa7 104 multiverse/source/Release + 5644835af0d1ed82cc7c14e34c2a543f 9098 restricted/binary-amd64/Packages.gz + d3058923c862e74c2c08b9a4ad7ec51e 134705 restricted/binary-amd64/Packages + 97ecff09a695f1460177843ff5d2b3e6 103 restricted/binary-amd64/Release + f8ed966e5400930411a32a7183357810 8452 restricted/binary-amd64/Packages.bz2 + 60e74c701a6e40b7f869dd83b335ec5c 103 restricted/binary-armel/Release + 4a4dd3598707603b3f76a2378a4504aa 20 restricted/binary-armel/Packages.gz + 4059d198768f9f8dc9372dc1c54bc3c3 14 restricted/binary-armel/Packages.bz2 + d41d8cd98f00b204e9800998ecf8427e 0 restricted/binary-armel/Packages + 55c08a48fc4b3370acc95a391bde1189 103 restricted/binary-armhf/Release + ce2da4621bbbaf55d858ae4243e17715 1103 restricted/binary-armhf/Packages.bz2 + b26814493282faf0c5b269c44b799653 2477 restricted/binary-armhf/Packages + 784050b4fd16ea71e10cf130e47132d9 941 restricted/binary-armhf/Packages.gz + c4280a67444afbb8e2564d6f2249d397 9108 restricted/binary-i386/Packages.gz + 6dfd90555b37a912f82894b4ec3b63a0 8431 restricted/binary-i386/Packages.bz2 + 48d3e36bf54be9b3fc7576cfcd0aac79 134582 restricted/binary-i386/Packages + e49b38cbf4dc409e8c25f6ab4b32fbe4 102 restricted/binary-i386/Release + 4a4dd3598707603b3f76a2378a4504aa 20 restricted/binary-powerpc/Packages.gz + 4059d198768f9f8dc9372dc1c54bc3c3 14 restricted/binary-powerpc/Packages.bz2 + d41d8cd98f00b204e9800998ecf8427e 0 restricted/binary-powerpc/Packages + edb68a453747a9faa9e98389787fb79d 105 restricted/binary-powerpc/Release + d41d8cd98f00b204e9800998ecf8427e 0 restricted/debian-installer/binary-amd64/Packages + 4059d198768f9f8dc9372dc1c54bc3c3 14 restricted/debian-installer/binary-amd64/Packages.bz2 + 4a4dd3598707603b3f76a2378a4504aa 20 restricted/debian-installer/binary-amd64/Packages.gz + 4a4dd3598707603b3f76a2378a4504aa 20 restricted/debian-installer/binary-armel/Packages.gz + 4059d198768f9f8dc9372dc1c54bc3c3 14 restricted/debian-installer/binary-armel/Packages.bz2 + d41d8cd98f00b204e9800998ecf8427e 0 restricted/debian-installer/binary-armel/Packages + 4059d198768f9f8dc9372dc1c54bc3c3 14 restricted/debian-installer/binary-armhf/Packages.bz2 + 4a4dd3598707603b3f76a2378a4504aa 20 restricted/debian-installer/binary-armhf/Packages.gz + d41d8cd98f00b204e9800998ecf8427e 0 restricted/debian-installer/binary-armhf/Packages + 4a4dd3598707603b3f76a2378a4504aa 20 restricted/debian-installer/binary-i386/Packages.gz + 4059d198768f9f8dc9372dc1c54bc3c3 14 restricted/debian-installer/binary-i386/Packages.bz2 + d41d8cd98f00b204e9800998ecf8427e 0 restricted/debian-installer/binary-i386/Packages + 4a4dd3598707603b3f76a2378a4504aa 20 restricted/debian-installer/binary-powerpc/Packages.gz + 4059d198768f9f8dc9372dc1c54bc3c3 14 restricted/debian-installer/binary-powerpc/Packages.bz2 + d41d8cd98f00b204e9800998ecf8427e 0 restricted/debian-installer/binary-powerpc/Packages + 39ef6c1d54f83252b07406f9cc3e9204 2596 restricted/i18n/Index + a76089a7a653d4f2196c38093058d1aa 19001 restricted/source/Sources + 3990b36e6ef2846251b58a58cde3768d 5470 restricted/source/Sources.bz2 + f0a32107aaf12daf3e64b4dc3ee11321 5306 restricted/source/Sources.gz + 7871a3f6f83e033ab93c06bf886e305d 104 restricted/source/Release + 3464b1b15950e714151f8bb43982951e 25546870 universe/binary-amd64/Packages + 9340d5c4051da92820bb5bd5ba05f7a7 4785960 universe/binary-amd64/Packages.bz2 + 1f6974aea9904921afdb4d1c5d0e8578 6166988 universe/binary-amd64/Packages.gz + 75ea366982b4862a41d9640687778dd2 101 universe/binary-amd64/Release + 5492f7f7183461d52f8d58871026c3e8 101 universe/binary-armel/Release + 420abe7ca02b5cb2abcd1b273efcfea9 4667308 universe/binary-armel/Packages.bz2 + 4da3448f54e710222b26646b0bee14e8 6009219 universe/binary-armel/Packages.gz + e99405db74ba425a3f898fdda0a42113 24901082 universe/binary-armel/Packages + d0545845bbcff572a5c852b80582b269 5948128 universe/binary-armhf/Packages.gz + 8f0d262f1eb03fc3523cd80b3112a7e0 101 universe/binary-armhf/Release + a10169d0cc23f526bcee5769d27778b0 4618508 universe/binary-armhf/Packages.bz2 + 952259d2cdb2c85df177702ac92075a0 24642528 universe/binary-armhf/Packages + df43c3b4ec37e79a00023475a09e2bfa 6179579 universe/binary-i386/Packages.gz + cc44a3e2ad759febb38ef2bec15ab29e 25568759 universe/binary-i386/Packages + 826b1d8609f0944a6d2ae95617e4d05a 100 universe/binary-i386/Release + 50690005918dd03ad9b71ffffa678d6f 4795820 universe/binary-i386/Packages.bz2 + 8a1f21204f4178574251a2238c00f317 25188905 universe/binary-powerpc/Packages + 7409876b9e1238d5a147720b41233a26 6080488 universe/binary-powerpc/Packages.gz + 9bcc15c59aa3fbbd15f0d187fe90b353 4716652 universe/binary-powerpc/Packages.bz2 + c3bdb05d2be1efa2dca9d2bac4e85b13 103 universe/binary-powerpc/Release + f8259410f0e1ad66324dbce895fdde2d 15255 universe/debian-installer/binary-amd64/Packages.bz2 + ce60affbf23a069735c29951bfb0b818 17243 universe/debian-installer/binary-amd64/Packages.gz + 13ce59ecd4540ddef3670dbbed73cdbc 61801 universe/debian-installer/binary-amd64/Packages + 988da583db40ce21d400926641fe6ed8 113584 universe/debian-installer/binary-armel/Packages + 75381e3ed15a3a2fa1480fdea72cfd24 23193 universe/debian-installer/binary-armel/Packages.bz2 + 4a8e6a98277f254660e8690fd050b232 27397 universe/debian-installer/binary-armel/Packages.gz + 02e7128ef42cd61e66c768520961fb11 20065 universe/debian-installer/binary-armhf/Packages.gz + 851afb686177a6819b291a714fa15813 17619 universe/debian-installer/binary-armhf/Packages.bz2 + ce3b6645e37226c4047546a40675ecdd 76034 universe/debian-installer/binary-armhf/Packages + 229235ad9979a343e3bea9aedb5af8da 17260 universe/debian-installer/binary-i386/Packages.gz + 8065c9994844e578af00ef8794709b18 15272 universe/debian-installer/binary-i386/Packages.bz2 + f28d6328611ab1e382fb0d0e798aca97 61718 universe/debian-installer/binary-i386/Packages + 60f54adbd38213dbbfe5d638f98a17e9 61121 universe/debian-installer/binary-powerpc/Packages + 1d48a07b3f4214200ff3eb1c5894e4a1 15024 universe/debian-installer/binary-powerpc/Packages.bz2 + 51eb13c4b9baf089e4e8b0e85556b90e 16860 universe/debian-installer/binary-powerpc/Packages.gz + 155e0b646671f37a7fe235c4579e59f2 2922 universe/i18n/Index + 2ef7ccbe106edb394dc69d8511775122 21256524 universe/source/Sources + e52b7cb491cc6a950cd11fa6263d7330 5019105 universe/source/Sources.bz2 + c722166709cfe9c398643b9c1a443610 102 universe/source/Release + 5ddd8bd0dda063b203d1a1da150983a0 6238766 universe/source/Sources.gz +SHA1: + 0b326daa3b2ac8748ca10942aaec15ebdcc78b36 1640344 main/binary-amd64/Packages.gz + 8a6068a75feb86e12b088dad2478600f6670f2d7 7818931 main/binary-amd64/Packages + 19655f20d48d9819ad95f2c9ecc59e5b1d94c3d0 97 main/binary-amd64/Release + f9761ecf8536859ef38b670a7f17d83febec4a37 1272844 main/binary-amd64/Packages.bz2 + a3a5faadbdf0a49d1587f07181b9eca870cb24ce 97 main/binary-armel/Release + 3c5d8f3a401427110adfd7f7d65513bfa47b933a 1619078 main/binary-armel/Packages.gz + 4d54e387978fdf829b4ff7336ed4d02e61c54d6a 1257389 main/binary-armel/Packages.bz2 + 969dfd243cc3f514eea9914de571db28621cd9bd 7743353 main/binary-armel/Packages + f8f33265eab2ff9fd8a6353e014e36a9d318a54d 97 main/binary-armhf/Release + 1d210f8ad3547b771bc8c8d2a9eb5ee99d437d81 7620333 main/binary-armhf/Packages + 5057a8b2d11d2325bb2546ad6613517b208fff18 1257653 main/binary-armhf/Packages.bz2 + 25fc010c2789028727308fbf6132a8da387423b8 1617483 main/binary-armhf/Packages.gz + 79369a31bc481f7f9f71f666906c3bdb356c44d8 1273857 main/binary-i386/Packages.bz2 + aaadaa6eaf0b7e73b0d371cdebae573f28833a43 1641082 main/binary-i386/Packages.gz + 6f8e5e9dd04a2379a7c6d8dc23b4ff8df5584741 96 main/binary-i386/Release + 8509eead0c5e9410e23d4226ee5d190220db1275 7816415 main/binary-i386/Packages + 7da3fd8ad7102912a4cc9882c66fbb1b65edd4c0 1627734 main/binary-powerpc/Packages.gz + 8a0c3b7757b738a89644e8c5a3b9afed806d2f83 99 main/binary-powerpc/Release + 4063338a28f6504f7bc2f9c00fc34ac26fc5a1fa 1263942 main/binary-powerpc/Packages.bz2 + 81844e44aaf0ed255ca200e7316bc9279ef238b6 7661552 main/binary-powerpc/Packages + d17439034551742aaa4762b4c174c1d72881f49f 62166 main/debian-installer/binary-amd64/Packages.gz + 05e024776b06a40253b9e252caad6dc4a13a90b9 234592 main/debian-installer/binary-amd64/Packages + fa692a307ecab69c106a5253107f980527cf58a9 48784 main/debian-installer/binary-amd64/Packages.bz2 + fb8be98ef08265d2f101cf265b9bf37654d750ac 47964 main/debian-installer/binary-armel/Packages.bz2 + 8953964fd2b54539e8276237cd5e4e2d4f9dc2ab 230310 main/debian-installer/binary-armel/Packages + cfdde60bbcbfb25c66fa474d28217e03a4c06789 61118 main/debian-installer/binary-armel/Packages.gz + 468306dc06acc828c50196427ba324c8ce225c79 62777 main/debian-installer/binary-armhf/Packages.gz + 17e7331a837675de31c365529ea9454cc48baf98 49051 main/debian-installer/binary-armhf/Packages.bz2 + 3404140163a5acece9a054912abf72d11a5591d0 238862 main/debian-installer/binary-armhf/Packages + 2bb7e052999eadc333a9f6481bdc20acb238d4c1 52279 main/debian-installer/binary-i386/Packages.bz2 + b2ad69cd6759724461c3566d91c1c5ec209eba07 259996 main/debian-installer/binary-i386/Packages + ebd0ab3923b3df4eca53eb863773bf0a9a4c3a67 67180 main/debian-installer/binary-i386/Packages.gz + eff551b62b72a1c0b183d4903a1452f2be08f3da 246636 main/debian-installer/binary-powerpc/Packages + 5c8aa09d48d7a792d555e7b16f4c89733e8441af 50309 main/debian-installer/binary-powerpc/Packages.bz2 + 582a86208e89e77a7f284e10a50b9cceaf4358ee 64468 main/debian-installer/binary-powerpc/Packages.gz + f426621b1015147e766dc003d1d2f140dc9c062d 3706 main/i18n/Index + b22a946cdae39d29535a63b020c0f2ad74c3c992 4356187 main/source/Sources + 711225fd252e77d85c7bb992aeb5aa5e45414ae1 933770 main/source/Sources.bz2 + a8807bf20dbaceb9d408f959840951131fd7d9f9 1174967 main/source/Sources.gz + cc2d2f6ce53597666df1a5ab216a08f08995f43f 98 main/source/Release + 06b070fc1ae771806c65e791742832320cc588e7 119109 multiverse/binary-amd64/Packages.bz2 + ae591617f4b6f988d6534270d4c32e3f0876166b 151924 multiverse/binary-amd64/Packages.gz + a28786a87a6136fb74a005c480c78a152123b9c0 581550 multiverse/binary-amd64/Packages + 3860a3ce6d87bb8a43803a1048cc96d4de3ae8a7 103 multiverse/binary-amd64/Release + 4bae80c3f5270e45f825141bcadb94d7dd82cd0e 136295 multiverse/binary-armel/Packages.gz + 9534dfc2e4a40386f48eff79062ee1742212b7d3 519605 multiverse/binary-armel/Packages + 92d1536ae99c958afd74299ffe30bdc6800cd8d0 103 multiverse/binary-armel/Release + 8e3ec557dc8f750e82e8ed5cbb0c509182feba79 106873 multiverse/binary-armel/Packages.bz2 + 009531e7cfb08701883a9e7a5f50235325e109cd 104529 multiverse/binary-armhf/Packages.bz2 + 596a666233560852574d9bca0109f4933a12c949 505901 multiverse/binary-armhf/Packages + eca4ab620c41d76c00a9615d8530db5a9c918fe8 103 multiverse/binary-armhf/Release + 53916a24cff0523e218bfee2c5464866d2099042 133117 multiverse/binary-armhf/Packages.gz + a7518b6b3e693d840a49b125020785d2049e75b9 121196 multiverse/binary-i386/Packages.bz2 + 84069f1643bd0092f4ec1b24eb921310532d72b2 591662 multiverse/binary-i386/Packages + 1d42b054d297b33cf69af011fa91f601c6b1a1b9 102 multiverse/binary-i386/Release + 8eae892b29234e9aac4c58a7098b097fe5ebde16 154762 multiverse/binary-i386/Packages.gz + 873bc8f864de428a4a47a3afaf53bc3a3a6e81c0 105 multiverse/binary-powerpc/Release + 665942774934afa56721d082a398735a067afe91 107209 multiverse/binary-powerpc/Packages.bz2 + c965416be0f7bf88c78394becf4a72aee342b829 520882 multiverse/binary-powerpc/Packages + e304951d28df0b75065fd3ef8166c65415a3cad2 136930 multiverse/binary-powerpc/Packages.gz + da39a3ee5e6b4b0d3255bfef95601890afd80709 0 multiverse/debian-installer/binary-amd64/Packages + a0fddd5458378c1bf3c10dd2f5c060d1347741ed 20 multiverse/debian-installer/binary-amd64/Packages.gz + 64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 multiverse/debian-installer/binary-amd64/Packages.bz2 + 64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 multiverse/debian-installer/binary-armel/Packages.bz2 + da39a3ee5e6b4b0d3255bfef95601890afd80709 0 multiverse/debian-installer/binary-armel/Packages + a0fddd5458378c1bf3c10dd2f5c060d1347741ed 20 multiverse/debian-installer/binary-armel/Packages.gz + a0fddd5458378c1bf3c10dd2f5c060d1347741ed 20 multiverse/debian-installer/binary-armhf/Packages.gz + da39a3ee5e6b4b0d3255bfef95601890afd80709 0 multiverse/debian-installer/binary-armhf/Packages + 64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 multiverse/debian-installer/binary-armhf/Packages.bz2 + 64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 multiverse/debian-installer/binary-i386/Packages.bz2 + a0fddd5458378c1bf3c10dd2f5c060d1347741ed 20 multiverse/debian-installer/binary-i386/Packages.gz + da39a3ee5e6b4b0d3255bfef95601890afd80709 0 multiverse/debian-installer/binary-i386/Packages + a0fddd5458378c1bf3c10dd2f5c060d1347741ed 20 multiverse/debian-installer/binary-powerpc/Packages.gz + da39a3ee5e6b4b0d3255bfef95601890afd80709 0 multiverse/debian-installer/binary-powerpc/Packages + 64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 multiverse/debian-installer/binary-powerpc/Packages.bz2 + 09a8aff01c419e0eae19749acf3b223e1f95eccc 2676 multiverse/i18n/Index + a088c61bca210afebf4c53904049e2a969d8ece3 154990 multiverse/source/Sources.bz2 + df4078a91645024ce93b1ee363003c83ffa2aa84 628753 multiverse/source/Sources + e6ec0430d594fa7fa2c98cb9a5fa8ac7ed0d506d 188325 multiverse/source/Sources.gz + 0750588f28b1c2cf6a005501c7d027cfa663cce1 104 multiverse/source/Release + 200fdeee1984ac78b6fdabfad34d2b485512ca2d 9098 restricted/binary-amd64/Packages.gz + 0e7ebd3d2690c7f89d19f8b337cf292cac913c18 134705 restricted/binary-amd64/Packages + c968d68baa554ffc7009688ee7d0d3e70663243c 103 restricted/binary-amd64/Release + 4185a5b6c2e702ea4754437ebfef23d828ec67a0 8452 restricted/binary-amd64/Packages.bz2 + 27886dcc6c7d08369cc65d4c35f26b806f57be56 103 restricted/binary-armel/Release + a0fddd5458378c1bf3c10dd2f5c060d1347741ed 20 restricted/binary-armel/Packages.gz + 64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 restricted/binary-armel/Packages.bz2 + da39a3ee5e6b4b0d3255bfef95601890afd80709 0 restricted/binary-armel/Packages + d83803a5f6c2f5c7321d68d126733b6015c8e2a9 103 restricted/binary-armhf/Release + 6607111b78dcd3de05cb88692c1e2142abf9a4c1 1103 restricted/binary-armhf/Packages.bz2 + b9f55d161632f89b5125a638ca6ad4fe5e9d11fe 2477 restricted/binary-armhf/Packages + d0c0a616aeac580d13256693cfbd507ae7c9b280 941 restricted/binary-armhf/Packages.gz + f3e483bbe77cbf0f64accbd0291df19b4e4d694b 9108 restricted/binary-i386/Packages.gz + 48d76b03a19e4d66d6f7a20339dab91acebaba99 8431 restricted/binary-i386/Packages.bz2 + 3ca46ea8f32b7cbc49ce76dd1c1ab91589900fd7 134582 restricted/binary-i386/Packages + 2aad61f5084ecdd64ff520520d77e980e8b21f81 102 restricted/binary-i386/Release + a0fddd5458378c1bf3c10dd2f5c060d1347741ed 20 restricted/binary-powerpc/Packages.gz + 64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 restricted/binary-powerpc/Packages.bz2 + da39a3ee5e6b4b0d3255bfef95601890afd80709 0 restricted/binary-powerpc/Packages + 6b0a230bbf47463e3d7e88f535e210aaa96a1251 105 restricted/binary-powerpc/Release + da39a3ee5e6b4b0d3255bfef95601890afd80709 0 restricted/debian-installer/binary-amd64/Packages + 64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 restricted/debian-installer/binary-amd64/Packages.bz2 + a0fddd5458378c1bf3c10dd2f5c060d1347741ed 20 restricted/debian-installer/binary-amd64/Packages.gz + a0fddd5458378c1bf3c10dd2f5c060d1347741ed 20 restricted/debian-installer/binary-armel/Packages.gz + 64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 restricted/debian-installer/binary-armel/Packages.bz2 + da39a3ee5e6b4b0d3255bfef95601890afd80709 0 restricted/debian-installer/binary-armel/Packages + 64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 restricted/debian-installer/binary-armhf/Packages.bz2 + a0fddd5458378c1bf3c10dd2f5c060d1347741ed 20 restricted/debian-installer/binary-armhf/Packages.gz + da39a3ee5e6b4b0d3255bfef95601890afd80709 0 restricted/debian-installer/binary-armhf/Packages + a0fddd5458378c1bf3c10dd2f5c060d1347741ed 20 restricted/debian-installer/binary-i386/Packages.gz + 64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 restricted/debian-installer/binary-i386/Packages.bz2 + da39a3ee5e6b4b0d3255bfef95601890afd80709 0 restricted/debian-installer/binary-i386/Packages + a0fddd5458378c1bf3c10dd2f5c060d1347741ed 20 restricted/debian-installer/binary-powerpc/Packages.gz + 64a543afbb5f4bf728636bdcbbe7a2ed0804adc2 14 restricted/debian-installer/binary-powerpc/Packages.bz2 + da39a3ee5e6b4b0d3255bfef95601890afd80709 0 restricted/debian-installer/binary-powerpc/Packages + d59f5ac2532dcc7cb2f1e5b788c700bf8ab13b66 2596 restricted/i18n/Index + 8a80cdcf50cdcabcf4f47c772d7b252587cc9dc1 19001 restricted/source/Sources + ff7d82cf1d965953c745d224a1d4adc67b586528 5470 restricted/source/Sources.bz2 + f64da9da2038712c5d73ce3337e91d92ee39cd30 5306 restricted/source/Sources.gz + 5c963f5f4d4720afa5fbb914375d0033bcd50078 104 restricted/source/Release + 10c6989f4a241aabe00146905e776391fc4d9ac0 25546870 universe/binary-amd64/Packages + f6900616102430e0eafa8ac89795efff7edc0710 4785960 universe/binary-amd64/Packages.bz2 + 4f938bde9dff32a49bccd917613666017185882d 6166988 universe/binary-amd64/Packages.gz + 9d6cba1ed46b5eee1f6c065934e5f4854b3efee5 101 universe/binary-amd64/Release + 3573e863c714c0a083f9c962ea9136916f796e92 101 universe/binary-armel/Release + bb8f53ead3723737c13950e5343327884f737da9 4667308 universe/binary-armel/Packages.bz2 + 43d9a98706b6e50c21092ce35313b5b034f30d01 6009219 universe/binary-armel/Packages.gz + 7f97dcbe710882d281efcfd2f8d70ca7d4e47265 24901082 universe/binary-armel/Packages + 8f6d42d7f8178a51a7065d7bf3234eecbca12810 5948128 universe/binary-armhf/Packages.gz + ea648f433d0edd47de820582fa6a1cd89ef66681 101 universe/binary-armhf/Release + e6ad9bdb18ce9e09e262b9e6f85b0b307a3456f1 4618508 universe/binary-armhf/Packages.bz2 + ba55530da6c3a9604977ea4a37b4b4d8943ff994 24642528 universe/binary-armhf/Packages + 05de59263866a33c104787943347164e7b124aba 6179579 universe/binary-i386/Packages.gz + 286a3dd2fda0d98d2ff14eafee0bba5c912d6df2 25568759 universe/binary-i386/Packages + 839529b6f6e2a64465e4a825fa5ad46a36f1c73d 100 universe/binary-i386/Release + 70c27be4d8bc87dc26bbe6f21fbb7328dc1c4d01 4795820 universe/binary-i386/Packages.bz2 + 06af7fdef1a54920a7667728a7b810553d00a9c8 25188905 universe/binary-powerpc/Packages + 4df1b07075b25ccae6e60d26d5a5761444ece689 6080488 universe/binary-powerpc/Packages.gz + 15d041ad1284527b07f75218cf6eb32322092f84 4716652 universe/binary-powerpc/Packages.bz2 + 42d6a46ed2e525b219f8f6dc076dadbd06fc7f1b 103 universe/binary-powerpc/Release + 92c3bef6ad40051021a4e9dadb16e5edc7410b57 15255 universe/debian-installer/binary-amd64/Packages.bz2 + 31d8725b0d238c282d9b572bb56b7e45c0ff53f8 17243 universe/debian-installer/binary-amd64/Packages.gz + e334a7c80e14dae3055950d9e45213db65d4087b 61801 universe/debian-installer/binary-amd64/Packages + 1fd1ae2b87eb85525b173ea982d15f3c98e6e33d 113584 universe/debian-installer/binary-armel/Packages + c56579feb77b5aac2d261abbbb6c89a1458ca4d9 23193 universe/debian-installer/binary-armel/Packages.bz2 + e4b08e57397f3ab0599e0bf6a2fbcba3aed438b5 27397 universe/debian-installer/binary-armel/Packages.gz + 5a9608213061eab983392258288e8aec36d006f0 20065 universe/debian-installer/binary-armhf/Packages.gz + dc558d56aef72991a3188909a14f752aabdee325 17619 universe/debian-installer/binary-armhf/Packages.bz2 + c6afa0e14c706aceea60aad033b6a067320fc165 76034 universe/debian-installer/binary-armhf/Packages + f359cf916a19055133546a7b7f3e35c7c260488e 17260 universe/debian-installer/binary-i386/Packages.gz + 23920ee4974d88ba824b0e884f8df6e2711a20db 15272 universe/debian-installer/binary-i386/Packages.bz2 + 21cfd020eefc848307fac14b8f0efe0d6cd9c6ea 61718 universe/debian-installer/binary-i386/Packages + f2ff72c8f1fe4ce40ccf44f8ccd6623cedf4e6f0 61121 universe/debian-installer/binary-powerpc/Packages + bd9c731941b261b22c022d97ca139bfeb1ad70ba 15024 universe/debian-installer/binary-powerpc/Packages.bz2 + e173071bda799068783c9192bff6536db9790a27 16860 universe/debian-installer/binary-powerpc/Packages.gz + 59a86abaed7cab292600b6766b18752b7e7c3d49 2922 universe/i18n/Index + 4b0ed5f327b0fa9b3f9d9410933a3d2afe467a7e 21256524 universe/source/Sources + d0525203f9ad5ec9183996e6765d0ef9a024691f 5019105 universe/source/Sources.bz2 + 00847d46051ba44d436000b0394b218503de125b 102 universe/source/Release + d9706a8ab2ffeadb51b50d042712536a95dc4343 6238766 universe/source/Sources.gz +SHA256: + 0d61aacd269015c0abfe01fe7f90a4f534c368e9c513f7e90d3111af82656b3d 1640344 main/binary-amd64/Packages.gz + a1bc8d839ca9966a0b924e4a4c60f1c23b4d431deb81e1bc529edf95f30fc29d 7818931 main/binary-amd64/Packages + a55d3b2e6e2a175529d73e6ca92989018cf57745e705f7ff675b05f80e5141f7 97 main/binary-amd64/Release + cc0d3a19c51188b4b4acb80e3013264462c6e0f60759bfd46206c60681bd4ba9 1272844 main/binary-amd64/Packages.bz2 + a841750f49bd11f99b9dae6941d2fa6ec1fd87906139d0ceeacf0d4df57a87cf 97 main/binary-armel/Release + e80eaf12c1aa520b353de8ad97e79364779e82ef011cb93db372edc900eb7be9 1619078 main/binary-armel/Packages.gz + 0ab0929c3c44837886e532f8ec4bee77f3664bdcc2cc3192a02b991c52b156ce 1257389 main/binary-armel/Packages.bz2 + ea400cf67f84c12265e4bf419de442a38880fab37d76999985972fc6df3e13b3 7743353 main/binary-armel/Packages + f3c40f057bb085f28ef2ed950f62366483d2a418571435c355dc27c0912dccff 97 main/binary-armhf/Release + cde037224f43e4619213c5195f2ea5c2f91d078f449579652dbd4128793d5062 7620333 main/binary-armhf/Packages + 7c6ea67e609b96dec6f2185df4cd81160e37ba467f9132a9bfb101da3f9a0468 1257653 main/binary-armhf/Packages.bz2 + 2b83bf5501ecae3347e5c96658edae7d48eef42108b4786471a3de241e75e7d3 1617483 main/binary-armhf/Packages.gz + 4d74c53917b84d37cb3277e2b755672a8733e2cfaf949f6e644e6e88094cdaa2 1273857 main/binary-i386/Packages.bz2 + 07f33bddfefdb4a0c44ddee59fd3eca497df2ad0456e0eeade136e4f0302ee3c 1641082 main/binary-i386/Packages.gz + 5182e22f799fe66c8db6dfb073fb040e9e583d88bb9d4d77e058b2afb87e9479 96 main/binary-i386/Release + 4cecfc8c0d2113d51b03afa8fdcdcc963d9ad74474696472ec1cdbdb38b856e2 7816415 main/binary-i386/Packages + 2795904625f466b4a2fb96d41c00b000ab7f2bdc7f288b0c9ef1283d7e110f87 1627734 main/binary-powerpc/Packages.gz + a9247e6d8b0c5977bc1e72be09b1f42a83b5f5a6a70b17f4fef35a0657e3c206 99 main/binary-powerpc/Release + 6e745b7edcd67755fa09f54cc3afdd0ffbd0475302a74293472e97e46ba75ddc 1263942 main/binary-powerpc/Packages.bz2 + 8b953dbae4a14e7ab47151044a47c7b0f0e1dd2a6480170b8172e00d9dad7a2a 7661552 main/binary-powerpc/Packages + a5bdf4116ecfeda052d5b3751138c6153e814ac58b2f551503f3ed90e6c3510c 62166 main/debian-installer/binary-amd64/Packages.gz + 6a9a4837a4a7df3e7e0566b354b7f1dd2dcf46254335ae3d06a72538f85e410a 234592 main/debian-installer/binary-amd64/Packages + 0da4f8190eebfef22103f1f6f7051adbe9489d454ab7224f09d05646407881e8 48784 main/debian-installer/binary-amd64/Packages.bz2 + ea01244357deb22c2a4bd7eaa34a1635c0915b89ce174f312c0e0a4b081eaf30 47964 main/debian-installer/binary-armel/Packages.bz2 + 4177b0519c75f7f950e5a0f0d72d40cc0c4ccf29ebe89fbb9bc1f11a80874526 230310 main/debian-installer/binary-armel/Packages + 2b6f81ef9fa687bfb2eb56bb3e90faef0c012351d096b141caa710fd50846043 61118 main/debian-installer/binary-armel/Packages.gz + 52c834247ff3a5475466e647802f6eff393f85589e5da5fd3e5b497669b8b49c 62777 main/debian-installer/binary-armhf/Packages.gz + 7090f1ad1307a012fbfff883885f16099ed66ebffdeece356f837e632b177a4f 49051 main/debian-installer/binary-armhf/Packages.bz2 + 4bae13f507993e977c279937406fc03e37fede7805a92508f6d3cba76f1aaf95 238862 main/debian-installer/binary-armhf/Packages + d1d23926ff15cfaa6160c5fd0327d181721093fbd2f2e8125be5559a991a81a8 52279 main/debian-installer/binary-i386/Packages.bz2 + 30e0ec7a2c3d47d5501de8414b436482ff523e9c4983b536b2c9911a30618b98 259996 main/debian-installer/binary-i386/Packages + 7a4dcb001ed4bb5fa2458af901de312e11a745bc86a0f877e47567d0f911bc0d 67180 main/debian-installer/binary-i386/Packages.gz + 30c2f590c2dedc9f78dfc7f0026b51bc9baa712ac8c9310404d9d6577af77d90 246636 main/debian-installer/binary-powerpc/Packages + 6c53fab780cf774c5cabb1788eea1e3446c528cde4352d106907f4ec22449370 50309 main/debian-installer/binary-powerpc/Packages.bz2 + b003f3fbf2fa6dbf7d47cf3fbd029ecd86b316ec497a9ac4eea3614cf4ec76af 64468 main/debian-installer/binary-powerpc/Packages.gz + fefed230e286d832ab6eb0fb7b72442165b50df23a68402ae6e9d265a31920a2 3706 main/i18n/Index + bb618cebb361a2a7148be0bad9af012c8d9de23dbc32d6d9ba035fa6ee0078ab 4356187 main/source/Sources + 0aeef2c2258136f9f774c36a158cf759389acf6a35a3153a03d3fa41d4f346d5 933770 main/source/Sources.bz2 + 4a058ba65244e8eaf17d159b72edebe4e621d54c274a82d4a973b358b4af9a28 1174967 main/source/Sources.gz + 864ba9a26e348c6297c08c047d8c228e5ed031ec3d46ef7aad93c3fa550395a8 98 main/source/Release + 85477d2b2e7ea2f46b6a059f7526cf52d75fea1a5120aa3b256c576e904d40ff 119109 multiverse/binary-amd64/Packages.bz2 + 2967ae6c1cc065bec03225d808b4511b138cc13b8de801a0562fec6e30710f36 151924 multiverse/binary-amd64/Packages.gz + 18fcf61bb74ef2a01c3d4a8d4646a75836f43244168b43d6ae202f368167b224 581550 multiverse/binary-amd64/Packages + fbc4931ef84d50a39da65d110f787aee274df8819a758a3c0aa1ff13f0ba6ee0 103 multiverse/binary-amd64/Release + 49f48a34696d08a13a0fdc19a0f6896af2cb477e72860a8880954926c7d45e60 136295 multiverse/binary-armel/Packages.gz + f20d7f0bc32b5b2fbcb442f7c128aaad7e18aece3781d53f560932bb191d6830 519605 multiverse/binary-armel/Packages + f7ea72b2c07af81f2e342414025dce7a658a6a9915c4d8adc13b992cb3b9fd2f 103 multiverse/binary-armel/Release + dd3d4e8a6ec9055d5b553af49822de74648f071ceb0fd314d6cd1aaf7ad6882b 106873 multiverse/binary-armel/Packages.bz2 + 567c1f9d30a4d6650552d66c5fb43d2d8910d3fed69793daed622d2c699f4bc8 104529 multiverse/binary-armhf/Packages.bz2 + a47ef2c0a68adeb70a0bc6b22c94b08402396ff6f5c77664e06c2fb7ee0e7ab0 505901 multiverse/binary-armhf/Packages + 6b95e8edaa2bb799f6e15a4a6aaf223da0faea670cd03340395bdcea90205afc 103 multiverse/binary-armhf/Release + 14721b333f19a6344addb185f161d1cd14e04ac284c8fa9d726064ec228269a8 133117 multiverse/binary-armhf/Packages.gz + 454436f374186007075445c1f206ba5c926f30609baa732c495f1ba456d71e59 121196 multiverse/binary-i386/Packages.bz2 + 9fabd7bfdbfd216968f7a17265e5609cdd72f1ea7c8f50941e294694e76b180d 591662 multiverse/binary-i386/Packages + 7141881b898ac6a78f1ca6f3e81481ee6657f6762fa22768816ab39f6b17e695 102 multiverse/binary-i386/Release + 3f4cae31df741f55d523ecea758d05a7e012a205bb03974ee20eb09e3f4fa63b 154762 multiverse/binary-i386/Packages.gz + 332dde644a8467496eb5f45ffd2d735ca61ea781da21cd205b3267cd83fa0563 105 multiverse/binary-powerpc/Release + 99ef0a611aa32ffa4f16a006d641fbd8dd9e3e73bde3c93b831cd6583746e64b 107209 multiverse/binary-powerpc/Packages.bz2 + 60f2431dab7bd02fe2c2428bf400c3535be49641cc9d5645a8f1b4fd44f5086f 520882 multiverse/binary-powerpc/Packages + cacfd10b40992a617ce32c479f9505531c8cc57e4cf964687d663a5f41f8dcbd 136930 multiverse/binary-powerpc/Packages.gz + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 multiverse/debian-installer/binary-amd64/Packages + f61f27bd17de546264aa58f40f3aafaac7021e0ef69c17f6b1b4cd7664a037ec 20 multiverse/debian-installer/binary-amd64/Packages.gz + d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 multiverse/debian-installer/binary-amd64/Packages.bz2 + d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 multiverse/debian-installer/binary-armel/Packages.bz2 + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 multiverse/debian-installer/binary-armel/Packages + f61f27bd17de546264aa58f40f3aafaac7021e0ef69c17f6b1b4cd7664a037ec 20 multiverse/debian-installer/binary-armel/Packages.gz + f61f27bd17de546264aa58f40f3aafaac7021e0ef69c17f6b1b4cd7664a037ec 20 multiverse/debian-installer/binary-armhf/Packages.gz + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 multiverse/debian-installer/binary-armhf/Packages + d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 multiverse/debian-installer/binary-armhf/Packages.bz2 + d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 multiverse/debian-installer/binary-i386/Packages.bz2 + f61f27bd17de546264aa58f40f3aafaac7021e0ef69c17f6b1b4cd7664a037ec 20 multiverse/debian-installer/binary-i386/Packages.gz + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 multiverse/debian-installer/binary-i386/Packages + f61f27bd17de546264aa58f40f3aafaac7021e0ef69c17f6b1b4cd7664a037ec 20 multiverse/debian-installer/binary-powerpc/Packages.gz + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 multiverse/debian-installer/binary-powerpc/Packages + d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 multiverse/debian-installer/binary-powerpc/Packages.bz2 + f0b16a5cfd2d633c9ddecfadfa6742544b18c23ed30023286e2b20ef29f33c73 2676 multiverse/i18n/Index + faa0360612fc00453dfdd55b6a1bb20e4f876e041ad6fca410d5da65608ab31e 154990 multiverse/source/Sources.bz2 + 2f0deae62e2cf7e5257bbd858cb0bf2a94122c4eb82be13e13768d0b9ce84c9e 628753 multiverse/source/Sources + 28f6d95fcba03e442cf24dc547653d5ec60177a29d7cfea771efcc5501077747 188325 multiverse/source/Sources.gz + f35f721bf16691842cc916c3563fab535f6bb83329f40c33ac02f4ba637707d3 104 multiverse/source/Release + 3e872fa356cbce4dfd75a88caa4fc6b47616e1fc7d224f4fc2123650fd7f4be3 9098 restricted/binary-amd64/Packages.gz + 459a26c3ef3cb5db8c8355ea6abfa8cfe0a7a266a197929d86d37686daf8a337 134705 restricted/binary-amd64/Packages + ea47572182da041b46543e471cb7a6fcc4e001fbe19a27740085ebf5d77252a9 103 restricted/binary-amd64/Release + adb08d7f0fa444f2869e8d932db7adb1515839f11af6032284cf1e20060e2dd6 8452 restricted/binary-amd64/Packages.bz2 + 65a5ac0820d61383f7dcf33699aa029b5965b7906bc8341f94f8f7f354cdcd83 103 restricted/binary-armel/Release + f61f27bd17de546264aa58f40f3aafaac7021e0ef69c17f6b1b4cd7664a037ec 20 restricted/binary-armel/Packages.gz + d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 restricted/binary-armel/Packages.bz2 + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 restricted/binary-armel/Packages + ee447ce81793bd3bc8c127d4e065c6ec24e5901573dffb7cc5abedfbcb86592c 103 restricted/binary-armhf/Release + d88ed7df97cd60cdce35c3ca81de66e2bedf0f22e67ec8922dbd5eca545b5e50 1103 restricted/binary-armhf/Packages.bz2 + 9ade66f4a49598fb371705a79244e5f3abb74c04467f9f9954641ae5acec6766 2477 restricted/binary-armhf/Packages + 03d8b64c445f327ce9e369bca815652844bd6aafb344d0287fb4e71f321d0414 941 restricted/binary-armhf/Packages.gz + 07e344ed07234876c3fddd9aa763e04bfc2e013fc18428738be71abfb9e1ca77 9108 restricted/binary-i386/Packages.gz + 8061335b923c49e72a2b60b437d5bbad1b98a45ac178a68fd8359cec9fad27ec 8431 restricted/binary-i386/Packages.bz2 + 122336146860047af3d5817dbc423f01d57a90cbf41db1ee0ad9235c0559a43e 134582 restricted/binary-i386/Packages + 58634ed42b6fadb280d48f419b960e28151320a62b4486e520ca327719db554a 102 restricted/binary-i386/Release + f61f27bd17de546264aa58f40f3aafaac7021e0ef69c17f6b1b4cd7664a037ec 20 restricted/binary-powerpc/Packages.gz + d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 restricted/binary-powerpc/Packages.bz2 + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 restricted/binary-powerpc/Packages + d9bce398e46f0eac57d1d33fd8a6caa0bd7ab6334508c0640956cb7adbe1eba1 105 restricted/binary-powerpc/Release + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 restricted/debian-installer/binary-amd64/Packages + d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 restricted/debian-installer/binary-amd64/Packages.bz2 + f61f27bd17de546264aa58f40f3aafaac7021e0ef69c17f6b1b4cd7664a037ec 20 restricted/debian-installer/binary-amd64/Packages.gz + f61f27bd17de546264aa58f40f3aafaac7021e0ef69c17f6b1b4cd7664a037ec 20 restricted/debian-installer/binary-armel/Packages.gz + d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 restricted/debian-installer/binary-armel/Packages.bz2 + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 restricted/debian-installer/binary-armel/Packages + d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 restricted/debian-installer/binary-armhf/Packages.bz2 + f61f27bd17de546264aa58f40f3aafaac7021e0ef69c17f6b1b4cd7664a037ec 20 restricted/debian-installer/binary-armhf/Packages.gz + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 restricted/debian-installer/binary-armhf/Packages + f61f27bd17de546264aa58f40f3aafaac7021e0ef69c17f6b1b4cd7664a037ec 20 restricted/debian-installer/binary-i386/Packages.gz + d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 restricted/debian-installer/binary-i386/Packages.bz2 + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 restricted/debian-installer/binary-i386/Packages + f61f27bd17de546264aa58f40f3aafaac7021e0ef69c17f6b1b4cd7664a037ec 20 restricted/debian-installer/binary-powerpc/Packages.gz + d3dda84eb03b9738d118eb2be78e246106900493c0ae07819ad60815134a8058 14 restricted/debian-installer/binary-powerpc/Packages.bz2 + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 restricted/debian-installer/binary-powerpc/Packages + 17dde58abfdb4dfdad9c8a82db09c9dbc3d8a7cd84b51dd9167579d6899e9ff5 2596 restricted/i18n/Index + ee3655459e45778fdfa06fb649565e66b25d2dd0870c75890005fb3597bb71d7 19001 restricted/source/Sources + cff18d2ad74ead8712f1b77a23b32e84e54269b03ba2a409ae4227860d1181f5 5470 restricted/source/Sources.bz2 + cf085bdcb323dd2c2a599ddb7a9b3ae7bd37121f42024d68b367a4f735df900f 5306 restricted/source/Sources.gz + 9137393fc24cf64808d55ca7665bc5a7bd46b48918e6720a95ba239a8fab092e 104 restricted/source/Release + 901469729d2354891be94c192dabd8c1d0bc31e1497ea8360b70d2e847c1f3c1 25546870 universe/binary-amd64/Packages + 799347395d4e011a215aa5ce0c9006449d8af884795ffbce7a35767a55f99074 4785960 universe/binary-amd64/Packages.bz2 + 68b08847604c4efe7d6f56ba79f923ce0ab82127dfcc6e8cffaf12af25d7adba 6166988 universe/binary-amd64/Packages.gz + 52ffdd1777a886edc5e1e1ef430b03a72937920f9722fd453ee8243cb0aac860 101 universe/binary-amd64/Release + a78a1304e105b2fe4c950c77c1794f715c1256d14d8541cca8f5cd13db48119e 101 universe/binary-armel/Release + d6d4bfa5d0891086f5a4f2aabfaecd7a1e0c0d8b46aef33b3470e349e7a9210e 4667308 universe/binary-armel/Packages.bz2 + 374d50d0335c655da46f9cd54cd00d9a20058d2fe7c56989aa121b49883cfb88 6009219 universe/binary-armel/Packages.gz + ab5073e90417b729d1fe3b68052e6a8e66e48986c35470944f6a58676e967450 24901082 universe/binary-armel/Packages + af74034d1a3e1f90745dc48b996a98c471d997b12a1d810eb8754088540591d7 5948128 universe/binary-armhf/Packages.gz + 6697d196b35850817476e884fdc013d9670b4bac73310c54a4d62cd810f02c70 101 universe/binary-armhf/Release + 1ca17d3aecec2325cba53e1c299aeb6a1fed01d7acbc40163595de9e651abdeb 4618508 universe/binary-armhf/Packages.bz2 + 2b422ffa77d4374650d4cc543c5a1123b2535effb2c8cdaf25fd77d1dde632c4 24642528 universe/binary-armhf/Packages + cd6b5cb8165553482abee1bf85e5cd3288abadccb6acf34239ec45f79a090784 6179579 universe/binary-i386/Packages.gz + 8ef7db20ba08cf1b4d98a618189c615c69865f4da025ac654e3e6b8a4382a3ae 25568759 universe/binary-i386/Packages + 06af492500145bd64762d885417d167269db6ea03022c6968f1a5d0515ac55dd 100 universe/binary-i386/Release + 530a2efb8051a63ed17431ae0c7243df79ecb418acf1dadc2487cd6fd79fb420 4795820 universe/binary-i386/Packages.bz2 + 1e8fa52a64292d2c73cee0645d0eed5583ea7cc1138af4744838c6833716d638 25188905 universe/binary-powerpc/Packages + 5d2b8e23e0a16f13e25595b63807fb64afd9074aadf7a37b8e238b2011e894b8 6080488 universe/binary-powerpc/Packages.gz + eb482b008c8c882b349230abaa812ed6e545a2ef9132bb0d3d3bffa74da0c6c7 4716652 universe/binary-powerpc/Packages.bz2 + 98d44cc7544f79c18b8e8ea697d476e9b85d91088385b643c82d4064b21f4657 103 universe/binary-powerpc/Release + 3da2d1e57aaca628148e2688a951cbb784a9a54b7f6b1f84d530add1b66fcceb 15255 universe/debian-installer/binary-amd64/Packages.bz2 + 43f891ac590f44fde5854de9ba15222c088b70562f5dc4ff26064909e60cf62e 17243 universe/debian-installer/binary-amd64/Packages.gz + 3084a8a441e961eeb3865ff411557166ec105be86a55df268cdb6725f49e1f67 61801 universe/debian-installer/binary-amd64/Packages + a1ff01f18766744f36d0774a68d8a89355246c585c4b28ee18e5e139fafae530 113584 universe/debian-installer/binary-armel/Packages + e0713f86f5f5121deb60ce61d774951468625184a7ae9576f81d70202ef585b7 23193 universe/debian-installer/binary-armel/Packages.bz2 + 5a8411e2b0648e553fa25ac82ea83fb17dd2d2a77bd10cec14cab12f5582d4c4 27397 universe/debian-installer/binary-armel/Packages.gz + b79c86d926c3129f5c27e50185157a78d85abde8ada90a9910338e660c4318be 20065 universe/debian-installer/binary-armhf/Packages.gz + b2113b25380423be8f6202a4860479e44a00072e46fa035f0da2f3a5a280de20 17619 universe/debian-installer/binary-armhf/Packages.bz2 + 3f023d2cc55d6ebab883f6f2d7305a4e3564f918f63ca4f745d6fd1318e67ab7 76034 universe/debian-installer/binary-armhf/Packages + 5ea61a62a3e8fc755c22e23c9d87b20924707c0986a490458472a3d7e9cbe117 17260 universe/debian-installer/binary-i386/Packages.gz + 7a90b014c655311e92de1ea4cf24e100665c564a2ed699df63d17c82ad9e1349 15272 universe/debian-installer/binary-i386/Packages.bz2 + 7e39417ce073e3a35d048847a29a0414af69c4e923c018dc22438319c79adea5 61718 universe/debian-installer/binary-i386/Packages + cdf17a791544d0c522fa853a23b317deffa76ac643e88bec0b84b0aa5afe957b 61121 universe/debian-installer/binary-powerpc/Packages + b470146da791dc4f4593d2bb00ea4e305d6f55f346a5f3ac6755d890a3318080 15024 universe/debian-installer/binary-powerpc/Packages.bz2 + 810d1590d1cd7298e1fd5465f85ba49b6ae79780b42d8e8b68aebb42283785ea 16860 universe/debian-installer/binary-powerpc/Packages.gz + 563a55a892e1ec8bf565e3294c033b4e8dbbbe4651e73733eac7338db77282f7 2922 universe/i18n/Index + 7bc01d4f10bbcf882ce6931aa9371b2de6b35277efc2ae52e233280dcd12a18d 21256524 universe/source/Sources + 95135631873f4dce05ba657478475033d02462bbb8f7263832585d1decb5c9b8 5019105 universe/source/Sources.bz2 + 0fd2ae580be352cb8ab4bb87e5504b78f78bcb7249b644719b3c2db3b5d3ca8c 102 universe/source/Release + d1dd96015e24dd369ea22413a2b876686a60c5d9d91958a5df3745a66289910f 6238766 universe/source/Sources.gz diff --git a/tests/data/tagfile/history.1.log.gz b/tests/data/tagfile/history.1.log.gz new file mode 100644 index 0000000..4174e02 Binary files /dev/null and b/tests/data/tagfile/history.1.log.gz differ diff --git a/tests/data/tagfile/history.log b/tests/data/tagfile/history.log new file mode 100644 index 0000000..f1d7266 --- /dev/null +++ b/tests/data/tagfile/history.log @@ -0,0 +1,15 @@ + +Start-Date: 2012-02-01 13:54:52 +Commandline: apt-get install chromium-browser +Install: chromium-browser:amd64 (16.0.912.77~r118311-0ubuntu1), chromium-browser-l10n:amd64 (16.0.912.77~r118311-0ubuntu1, automatic), chromium-codecs-ffmpeg:amd64 (16.0.912.77~r118311-0ubuntu1, automatic) +End-Date: 2012-02-01 13:55:01 + +Start-Date: 2012-02-02 10:39:04 +Commandline: apt-get install python-geoclue +Install: python-geoclue:amd64 (0.1.0-4build1) +End-Date: 2012-02-02 10:39:08 + +Start-Date: 2012-02-03 10:20:50 +Commandline: apt-get install python-qt4 +Install: python-qt4:amd64 (4.9-3ubuntu1) +End-Date: 2012-02-03 10:20:55 diff --git a/tests/data/test-provides/etc/apt/sources.list b/tests/data/test-provides/etc/apt/sources.list new file mode 100644 index 0000000..2955b5c --- /dev/null +++ b/tests/data/test-provides/etc/apt/sources.list @@ -0,0 +1 @@ +deb http://archive.ubuntu.com/ubuntu oneiric main diff --git a/tests/data/test-provides/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_oneiric_main_binary-i386_Packages b/tests/data/test-provides/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_oneiric_main_binary-i386_Packages new file mode 100644 index 0000000..f991cb9 --- /dev/null +++ b/tests/data/test-provides/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_oneiric_main_binary-i386_Packages @@ -0,0 +1,75 @@ +Package: exim4-daemon-light +Priority: extra +Section: mail +Installed-Size: 1092 +Maintainer: Ubuntu Developers +Original-Maintainer: Exim4 Maintainers +Architecture: all +Source: exim4 +Version: 4.76-2ubuntu1 +Replaces: mail-transport-agent +Provides: mail-transport-agent +Conflicts: mail-transport-agent +Filename: pool/main/e/exim4/exim4-daemon-light_4.76-2ubuntu1_i386.deb +Size: 451088 +MD5sum: 81795887e233ecfb3471e8a3da4c4b8b +SHA1: da0202f7da88b9e9c5ee326a24c3fdd640543a5d +SHA256: 5ffa03674b5198d1c0e9e0d9e3442cdd7fbe13226c7df91aa53def1f8b6c0d86 +Description: lightweight Exim MTA (v4) daemon + Exim (v4) is a mail transport agent. This package contains the exim4 + daemon with only basic features enabled. It works well with the + standard setups that are provided by Debian and includes support for + TLS encryption and the dlopen patch to allow dynamic loading of a + local_scan function. + . + The Debian exim4 packages have their own web page, + http://pkg-exim4.alioth.debian.org/. There is also a Debian-specific + FAQ list. Information about the way the Debian packages are + configured can be found in + /usr/share/doc/exim4-base/README.Debian.gz, which additionally contains + information about the way the Debian binary packages are built. The + very extensive upstream documentation is shipped in + /usr/share/doc/exim4-base/spec.txt.gz. To repeat the debconf-driven + configuration process in a standard setup, invoke dpkg-reconfigure + exim4-config. There is a Debian-centered mailing list, + pkg-exim4-users@lists.alioth.debian.org. Please ask Debian-specific + questions there, and only write to the upstream exim-users mailing + list if you are sure that your question is not Debian-specific. You + can find the subscription web page on + http://lists.alioth.debian.org/mailman/listinfo/pkg-exim4-users +Homepage: http://www.exim.org/ +Bugs: https://bugs.launchpad.net/ubuntu/+filebug +Origin: Ubuntu +Supported: 18m + +Package: postfix +Priority: optional +Section: mail +Installed-Size: 3472 +Maintainer: Ubuntu Developers +Original-Maintainer: LaMont Jones +Architecture: all +Version: 2.8.3-1ubuntu1 +Replaces: mail-transport-agent +Provides: default-mta, mail-transport-agent +Recommends: python +Suggests: procmail, postfix-mysql, postfix-pgsql, postfix-ldap, postfix-pcre, sasl2-bin, libsasl2-modules, dovecot-common, resolvconf, postfix-cdb, mail-reader, ufw +Conflicts: libnss-db (<< 2.2-3), mail-transport-agent, smail +Filename: pool/main/p/postfix/postfix_2.8.3-1ubuntu1_i386.deb +Size: 1221834 +MD5sum: c4575f03ef0711cc744d394ae36f4a8c +SHA1: f0f636c942981782cf23cee3d8a95aee188081b9 +SHA256: 13a4bfaf10c8addfc7dce01c0ea65bfbd6a759c4a2aaaafbae5855d099925fe0 +Description: High-performance mail transport agent + Postfix is Wietse Venema's mail transport agent that started life as an + alternative to the widely-used Sendmail program. Postfix attempts to + be fast, easy to administer, and secure, while at the same time being + sendmail compatible enough to not upset existing users. Thus, the outside + has a sendmail-ish flavor, but the inside is completely different. +Homepage: http://www.postfix.org +Bugs: https://bugs.launchpad.net/ubuntu/+filebug +Origin: Ubuntu +Supported: 18m +Task: mail-server + + diff --git a/tests/data/test-provides/var/lib/dpkg/status b/tests/data/test-provides/var/lib/dpkg/status new file mode 100644 index 0000000..e69de29 diff --git a/tests/data/test-repo/Packages.gz b/tests/data/test-repo/Packages.gz new file mode 100644 index 0000000..81daf2b Binary files /dev/null and b/tests/data/test-repo/Packages.gz differ diff --git a/tests/data/test-repo2/Packages.gz b/tests/data/test-repo2/Packages.gz new file mode 100644 index 0000000..81daf2b Binary files /dev/null and b/tests/data/test-repo2/Packages.gz differ diff --git a/tests/data/test-signed-usable-repo/key.gpg.base64 b/tests/data/test-signed-usable-repo/key.gpg.base64 new file mode 100644 index 0000000..3bdec88 --- /dev/null +++ b/tests/data/test-signed-usable-repo/key.gpg.base64 @@ -0,0 +1,62 @@ +mQGNBFzn06EBDADLLuONxlOlbDVZjkYPY6dJw16v5mSIL7r7BQ42ssUtO2V+B8bjTUCp3zRttadb +tWigfz/Pqz5u6XLz+NPn3Nby6wMVrpfjxgKqjGF4kQ3Wi4ThHlsvgL12KoIOOxhmIJ3E8uLklza8 +lkYVPtzP1bgRjRx1QKLvdVAIy6iWVfQ9Xa8OtVBs7XZArSZ57mR37deaMOtvBdk9SOPQ939BimmN +J9IuLSlzsaqTVtxYcT/F85U/EWSFa6s6BvoDwbOZfGTxjsSeADMgh7DuvcYhYB+1HtJAjUNurnrq +92Ymx/i5k4lULJ0C8T2P7jqc437q1kAMoxhr8VwmtrfwDYTGiRHR0x5LA0wekP1HPHHJfmemQcCm +2StjnMDEX16xuQsfwvkzbJvjULh1USR9Z7SPfWGcx28cUv71+34Us1YLUAvaaobjhX+zpcI1mn+o +ljxu56uuW6ZRsyHvbWFdTTKB8TWggkmMnHL8EowlBtvRQItgJllWfCs16Ga4UbR/7Qia6BMAEQEA +AbQjdGVzdEBleGFtcGxlLmNvbSA8dGVzdEBleGFtcGxlLmNvbT6JAc4EEwEKADgCGwMFCwkIBwMF +FQoJCAsFFgIDAQACHgECF4AWIQQkgGw+FXEYW1oehsQ03un1nJNh+QUCXfelQwAKCRA03un1nJNh ++YsJC/0b3Y3d6Esy1O8r30EBcv6XKsHG8bRm4jGFm5bfGHPoNefgJStWtoTSFtY6QKbdTJFx7Ucp +KuEPIFEaBw70RMUpO3OhYjmFTev13DQQyelhuzzDx7+Kxqq1FiqL14xFnTVLp5kVfEU9pZ5pZtWz +LvJYwtNhTLCth+9i6jaWzVOwTtQHxEEau2FC5Mwk/KwTOmEn9Bnt3WPjdoGzyitcvgOjga50T1mm +2Cjj8O5pDSG+Fwt5ZVbHBvEXxx+RI7QqEraD9QCjHauak0+ORnCBcFzoetBHCBZpA7t/Rr9FdGmt +9G5zSFUUU4Bgrm/kJyIL/RQWleuxny1+/PjUY/Hwpa6XBK5yzkSNuO+6xCJfaZekG2z3GNL5KaO4 +c0O50FFj/pxUKMZj+dyc9aSYvQI2dccxvSLpPSezGMXDLMeNyR5R+J15Ld3NpFwp/wLZzoBpT+OA +R2BKW+E+eoe1545naV4RM1fuN55oBTN6bJLLigsIaum7t3qZyRrMZGltZKRUqI65AY0EXOfToQEM +AKQhepnHxSE0Z39H2AKUg8fUuqvs7qCdm8fqooPX+pqBt+030AD8e2dsgXurqMK9cMXTXvsfWd58 +0ZwMowwDc6QsXdtU1v4HrUIE3wH/7q8CE9q9giXEXlOkJcvHLhLiczAXzZ0cRmotgNIAhMKGNfMK +CL3qZBOUphljuauNOklcHL0AcpU6NlDrzkNVaW4inmjkbAfQS8u+vEMx2sKcCBEJ8UOEcYEl4CaS +dHwGFboklHtRDVHJpCqdgdEkXylriPy1XId/jjRhHDQ5MYRFPg+cDNpmGAn4irj8nGlDhR106ole +QEcHyzsuoBMVRBC5EubQDjW7b0S5fV2ZXfs0gGOe/XDy+YMR/2XwNBNAlI+eZaBLxEoPdJSPiIr1 +VCvYVxke9oKC5gFd1gQ0O17OY1TjbeuXxx6RbOY8Rl14E/Y5YURhyAY84nQ7ibbUStsOR/YxL+2t +8mrNI1ljWj+Knp3EdVXSq1bfrzB+IiDO35ziw3zAJpdgG9hLiHWsBICLZwARAQABiQG2BBgBCgAg +AhsMFiEEJIBsPhVxGFtaHobENN7p9ZyTYfkFAl33pU8ACgkQNN7p9ZyTYflBoAv/de2tzgcWzksE +4OMNaQggXbYtUxOmgLRy8Hrd+oAYuz9xozdsGFJoMdJlJ6i+XAGaGVUd1313isdkuS5aC47pEpuL +G1V9qMQzAbY0oHyB5h+lZZVnLz1y3TZZDgvLY57xrYP6hTrwKkxxQ5ATkMhcxRBTRidxs9kJkx8j +eeH+kYXeA3dS6Vk1IBiiDxJ/jb7qJfU+yb+hAbK3iBKh/FNYQ2Qd/EeYq37PeIVdegMliKslbRX7 +fBs83P5ssy1Hci3T4l5ZKRppIRRdniD4cislFzAxCQefcVrF1Su2+cg+5tvYmSIH2OuY/rxJX6lp +IPcnzI0hwTQNAQIEOmtdUrOvJVRoLPCioi5G7pe1d5gssnyqrpILS+mFZvT+bSXFlfeMDC/eh6gz +1/WIO9ENqZ7/Tf23Fvt3shjg4EJ+IkwvjUZ+rTs0FPQ1xznjD82FPcSM6HX/jNpXnfwnYjjukdZh +4c3YFkkevPTmjTiV2m28vbl8V8mP3gjD3v8Tbjw0CbHGmQGNBF3zoc8BDADEOhWcVTKIFUEx+NaA +VEVwMk7z1F+61CBPjxLckA0izRP67AmqQ1ULulSF0mxI6xXC1tc3mmyKkYYJg8pIVx+gwIZlBgkH +FvzBFYIckuiALeYZstIi+3XzmO/bKgSWpsj1eD3qLjlao5hwz4cz9F6vco0Z+KXJc9l8EyHSjuzx +yDmiGMDA29kZq1WJmUag2Ft6F67/RnFwpiYTVVwK9jrJUT3hqoBaoSobJNCFFM/atvDYgwjgmBhY +Km936bkm0tTqGOHIxnHqFu+qQ5e60UE2cxASw5j/CIW8h+nm/BdW6MokIYr50b47KvIrDWACwPnq +tsj3kInmHByTJ+pstDFxdoQlbELjehusPEmhhUKmbsL36MyT/q6CuitiBHOJpZi1s2w/0FTnAHhV +xPLhxjd+E0DmPgrNJSdYrJtDo7nejUM46yMyLzB4gQQAt6HpSanva4U7UbJLZOPDunO4+svVFyOH +9SDJwbqkr3kXDICCIgjLVJMotTkKxeZcQd8RMC0AEQEAAbQXVGVzdCBLZXkgPHRlc3RAZXhhbXBs +ZT6JAdQEEwEKAD4WIQTU7y2+6XtyA9QVrHVH+cEvgOk5jQUCXfOhzwIbAwUJA8JnAAULCQgHAwUV +CgkICwUWAgMBAAIeAQIXgAAKCRBH+cEvgOk5jSroC/9RAhS2wB4srbjtBYcQIyx0TtB3oQcztSDI +gPcod7dUpLlsARJcX710SDCslTZxmBFuZEsXnNMy9Tld5Y9CuwWObNfGAWNWK+GE+GDaUJEVDCHp +gcQm1WLeQ1I3bcl5sQ0Lg9uI6JUX6rFSdjvnfsx1JohR5Nd0YJIVfnxnR3Oz+NAT1BwwDzxGaO97 +Gir7nb0/ZSxvYiN24R2bArIt9hPvojUcY02FSSNXx09xNxAe+XDPFyYbj28OLSeN4LR2EfDnKVxi +Qpiy+Feg96vOukmT9XojT0JNGvTypgUjMz/aRcGG+aXx/ubvc7dJ6uXcldR+u8rgn4AKZa7QRchW +Sfy9NM4YJGO2my5TtIc76ippsS6XymJ8dDw8NFjr2J2Nc5/XY/n8ppC2CJaPs2vkiCxDxBlKk/+E +0w4Zt9QBCjk1KIVjWDTKn7X7MnYAZ+28D4sXe2MSR8oXcMK1po61B3x6N+JfgV6Po1fTosTnkGYH +xmiRzORFqAMtg6ydLq/AFEi5AY0EXfOhzwEMALbGPWBHhYcKdotMKKX05IQm4WRHcMfa413pdPh8 +ZZYfRUP/unEi+Gaygu6wnERPo69czqBXn9jiX4mNQ2timsBWcXSCYG79wfReAem0lTdti48bjoz1 +nsjS4y0hJ2eOaH1w2FUa7mkGL10dhjs15asrVw2z7klQCV/ZeJMmWlts6+nTL2qFA5az13Apg2d3 +AqFgeKHLAACgU+QDG/2m8TiyeKslnZPRa0ASnE9S/3R9cgwnCtIcN330dcmGbiqkLE3ABfxSHpn+ +Ztiggdy6i4drqeSKp2wVtUKK5nhLg+sBvfXRZnrm80mIYI/7SQiF8V4oSycNierr9krQ2yGTRWik +pOyWXHW/AadEH3MOhQHI414sFHYtMOHRjC1A99v7cK3weTZxom1G9W37zTJozdzkRB3IPavDKQf7 +Xm8FEPmceK/Gx4CZwKEL20b8T3XTYOrdDqyPaIhxT5ACwH2UDD24Va2PRiqRhBPIyGBpNV8twtHu +7sUVEpWVVxO29GX1uQARAQABiQG8BBgBCgAmFiEE1O8tvul7cgPUFax1R/nBL4DpOY0FAl3zoc8C +GwwFCQPCZwAACgkQR/nBL4DpOY2Uwgv/SoBpYtV7nTYCByGl3h6a3iKSrntyUfaGYIgGXlTBJ8kO +o85MxD3VxxudY2414Sdd3Pg0lpYgSgmmHo3Wouv2ZLU7Hrrn3VwQccdCCqbiO01P8Y/byCawE2GZ +QGKkk6f6AMzlk9hM2mhmdmz+6gFU0ziYCTMM+mIsza8KI0PIeqU+vkN4gxlwkEmaUBsPukzpnQmd +zMoSD/njC7PO+nnmoN1hY7onOxRUnuqgEKBYjk4GL7Jw4rfBR8rSvyANGUeEkDlDoHa0Mg3MRF1b +a97Q4LQ2jZNrOUB2hj2zlPk4ZsH0zukcKUB45O1VgCSOlcPC7247QDZQl1xlNhMOk+2H9XumW9Gf +dgaJJbcXJg5jAfsQ31pqw3KrFXzGJvn2EM7oov6Lq0Vazayl6Xx0260+iOTQAFDKB7kWbpbJGduW +0e3yEHiNUEZnIdcuDuLD8Cm0EC4EW5RtExt70DTDeo/S1K4dsl1/KXwNl5P5L/e1cLDLUm2iLu9x +qipSuMIYrosA diff --git a/tests/data/test-signed-usable-repo/seckey.asc b/tests/data/test-signed-usable-repo/seckey.asc new file mode 100644 index 0000000..bcbf153 --- /dev/null +++ b/tests/data/test-signed-usable-repo/seckey.asc @@ -0,0 +1,158 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +lQVXBFzn06EBDADLLuONxlOlbDVZjkYPY6dJw16v5mSIL7r7BQ42ssUtO2V+B8bj +TUCp3zRttadbtWigfz/Pqz5u6XLz+NPn3Nby6wMVrpfjxgKqjGF4kQ3Wi4ThHlsv +gL12KoIOOxhmIJ3E8uLklza8lkYVPtzP1bgRjRx1QKLvdVAIy6iWVfQ9Xa8OtVBs +7XZArSZ57mR37deaMOtvBdk9SOPQ939BimmNJ9IuLSlzsaqTVtxYcT/F85U/EWSF +a6s6BvoDwbOZfGTxjsSeADMgh7DuvcYhYB+1HtJAjUNurnrq92Ymx/i5k4lULJ0C +8T2P7jqc437q1kAMoxhr8VwmtrfwDYTGiRHR0x5LA0wekP1HPHHJfmemQcCm2Stj +nMDEX16xuQsfwvkzbJvjULh1USR9Z7SPfWGcx28cUv71+34Us1YLUAvaaobjhX+z +pcI1mn+oljxu56uuW6ZRsyHvbWFdTTKB8TWggkmMnHL8EowlBtvRQItgJllWfCs1 +6Ga4UbR/7Qia6BMAEQEAAQAL9iC9Eg0zwa0BI9CkDCyh0zMxtwC39ANKrQXevXad +UrZkwp4qQAA4u/k0qyV1pqsEgkCpZGmzPE1INn+PP0I3F8ANB2/Jqb24rvRaW5e1 +SZTiseyjul3ucx96VKJGrxirMm/c3Rtx8KoGH0iJcmEoVyC6SmIOGBBphY+GZWRp +tL4feuQ77yyj9anDz7n1q4/BUalvMgI02+mGNM8pnyqes4W7CT6Msh/Tvfw3MebG +FMkFKDu5VikTRX8oTrRWfskMuttAqI4jASPZv8uRXMf8FOopDD6Q5B9tK84kd3DD +dQJiqxXReiINViXj3HICbwAZYDxf4KNen4jjdPLaShjy/26XqqsD483um/r/uQNK +xDrAgWhWssxh0rf1UCfw8IpZ4NQ6MIqsMkR59SrbwTXvNUXac6ngNB6zV0YTTrio +0k+++kOLA7Uz6IbVAzz1gVtdSecMo3CpcJpk3fvJEWLWU/+3b+wul/WaUW8hCNuP +DSJjzGpQeQadWY/3wubhWkfxBgDaohrURKeQ5Oi3PnPJz9ua3dg8iq9ThDD2vIzs +C7VUb6qYkzfBK9BLe6Xpnii1bDp+eOn5FPnadyVO7BNNa7kzxWBsDgOfDBV9Xsbm +621l+F7sxNcRt+eO+9Uk9sJv+sOOPVd8VhrkLZBgFTu4IBtvArmujsl+VVxScoby +VV+fJ7lVajSTsx2COx4OQExtfc0/lXiOEvhy2F3b216BWgS02ryjxNy1QXfITg1T +sT36GYclxYd5xyzyBl9iGhBa/sMGAO3oy4OdGrveEYmc/sppTLdyKMspOm29200V +POhx4GwbswIWF4nMAvIc++nzGiZ0GucuUaJHAO63xqyWvPSFSTz90rAc8ZhOPSjV +jBTvZo4P6vUNFHX26lpKXaOtwkjMXA0D0Ck16Z7qdN7n8sPM/68l1CHoBdSuw1SO +0oBypi3tL8lDfKraDUcLK9wWb/FawbKYsrMl5RpyDwS/XCVYRUtUqSFFS80EDQGD +PHD6vLHKYaakT5kbejnSQc+O0i58cQYAo4OEASZrxV/a8Kl0afoAntRqu2BZg1tP ++j51HYGykZI/erKcq05as0o/vVe3VPNI/hskgmEVFggKiTYAs4OGGfNhOvP2j/Uv +jyzPNmEMEGemPoEP5OmTCfrkDOJi0Y5xh83EOyB9H00GHNsxf66gTwOcvjHV2ze9 +Ihkwbll692rfYqiK7pKfP/VayBFsxmnNFNKMTcbP06W+ozjkIaUneqA3B+k8Uu0t +U1Ut2to0Y9/khw1CAYRxuwJ/aIlFPTqd2se0I3Rlc3RAZXhhbXBsZS5jb20gPHRl +c3RAZXhhbXBsZS5jb20+iQHOBBMBCgA4AhsDBQsJCAcDBRUKCQgLBRYCAwEAAh4B +AheAFiEEJIBsPhVxGFtaHobENN7p9ZyTYfkFAl33pUMACgkQNN7p9ZyTYfmLCQv9 +G92N3ehLMtTvK99BAXL+lyrBxvG0ZuIxhZuW3xhz6DXn4CUrVraE0hbWOkCm3UyR +ce1HKSrhDyBRGgcO9ETFKTtzoWI5hU3r9dw0EMnpYbs8w8e/isaqtRYqi9eMRZ01 +S6eZFXxFPaWeaWbVsy7yWMLTYUywrYfvYuo2ls1TsE7UB8RBGrthQuTMJPysEzph +J/QZ7d1j43aBs8orXL4Do4GudE9Zptgo4/DuaQ0hvhcLeWVWxwbxF8cfkSO0KhK2 +g/UAox2rmpNPjkZwgXBc6HrQRwgWaQO7f0a/RXRprfRuc0hVFFOAYK5v5CciC/0U +FpXrsZ8tfvz41GPx8KWulwSucs5EjbjvusQiX2mXpBts9xjS+SmjuHNDudBRY/6c +VCjGY/ncnPWkmL0CNnXHMb0i6T0nsxjFwyzHjckeUfideS3dzaRcKf8C2c6AaU/j +gEdgSlvhPnqHteeOZ2leETNX7jeeaAUzemySy4oLCGrpu7d6mckazGRpbWSkVKiO +nQVYBFzn06EBDACkIXqZx8UhNGd/R9gClIPH1Lqr7O6gnZvH6qKD1/qagbftN9AA +/HtnbIF7q6jCvXDF0177H1nefNGcDKMMA3OkLF3bVNb+B61CBN8B/+6vAhPavYIl +xF5TpCXLxy4S4nMwF82dHEZqLYDSAITChjXzCgi96mQTlKYZY7mrjTpJXBy9AHKV +OjZQ685DVWluIp5o5GwH0EvLvrxDMdrCnAgRCfFDhHGBJeAmknR8BhW6JJR7UQ1R +yaQqnYHRJF8pa4j8tVyHf440YRw0OTGERT4PnAzaZhgJ+Iq4/JxpQ4UddOqJXkBH +B8s7LqATFUQQuRLm0A41u29EuX1dmV37NIBjnv1w8vmDEf9l8DQTQJSPnmWgS8RK +D3SUj4iK9VQr2FcZHvaCguYBXdYENDtezmNU423rl8cekWzmPEZdeBP2OWFEYcgG +POJ0O4m21ErbDkf2MS/trfJqzSNZY1o/ip6dxHVV0qtW368wfiIgzt+c4sN8wCaX +YBvYS4h1rASAi2cAEQEAAQAL/AhVWNO5BGXIst6QB8QtxTkesHGtQHpwNioi3CiE +jUlN/8gwFsQODbf1FufwEcv9cV3h+wcWEuqMfNoG/DpObI8v334U4yuXuTDKbYY8 +9+Hz4Y0wJQ0E2OM3SOH9VXYJAF83Pi3Vcy/N6qX+976msNOLtWDrJzSlTf+pBBLV +Q1nZLu5buPWhtINMTbc2fXllkZRy0Jde+JI6N3XT8K8D3Bb9Yb4TWe38PdLHidmI +N48xb0aJmXsHGWo+gApd5eUE/CU5L9mfvKkLaQAigOIyWzv92Tt20t+33Oxk4UO0 +RZFRBq3jju4MUngH3bU1R3v1ZYNuw1owdzZYZplXOIWuBWbmvYSQihM2drbfOkbg +dVghJF1K5xuWMiyQBsEWo9SxA4zzkfE+3lZzdbHPHcZxSd6oPDkdQDZgC0mqi3jf +yi2vEiUYbEOzGryb/QP4NUcX3rX71kr5yQZE7gT5GOI7TjwAsGAr8jCkQcYBPrP8 +HLkDHeNAxHE4qR5CipinYoxrFQYAwGsqg/WR6xEAAW6PJ0Cr1Jz2ifrm7ZaEFvRm +OJx6fN4aQyqDM0LG3sAArv6fHhAUQ6fkfu9URLsSiXzf8H2XXd1trKhi/Auq3qnA +nLBYgEv57DpOrGV1ZX6GXganBl586JqXqiee5W3ziBMPFLVC5jnd0D6Ctmoa6YHy +Sdsn2ne+Ax+YQEczfe5E83rWUvLpf4LZkBOgEP5InU5S1gC6DIbzbfVMGslbRoQc +AgMkP7aY4QnUuZ0IIGg5bjUiJXOtBgDaXWxiH5n7EKK3FJEnLwGHMZ2x7dbdAk7u +hS4HTB9Q4KvQUekw6I89SUp85p9QOMmke2JhTGbLjd3AFWzHFesRNVq8P05rmDQw +prkoaw7keG1JG8a+h72ndCciPx4jS5iRIz+pjm7SP87/7uPGJn1CEhZ8GJQZ9+Cl +dViLiK83eN7nqbaDzlYWDvr8avBVtA+UEPwY5OjoXxWskiK8uphXAbM7Ro1jhTJ3 +OivgpZhFrmyqqf7HGMtn5u+Jywj9/eMGAI5JjOyJQ5bdzfPeKECusKqwS+0dkkup +BQonT49jjmW1G2e+RY7l0xTG+DbUu4CRKGhMSgP11yjvT3kIW2A+AIEMfiitToET +4XCjyVoPlCN7vNneLbVPzpSBfvRwv7x3g96DLcLkssbDU2HDldwWDRhu+7e8gQYK +BC+13u3Cd14tD+d3VRCXMB9udnNNfZ9sHDb0YjZBbWsBhQgKrg5uscDw3XfOOZPv +Jj7t6NcsNVwaQQwPvutcCPZUsNNbSXWmctXViQG2BBgBCgAgAhsMFiEEJIBsPhVx +GFtaHobENN7p9ZyTYfkFAl33pU8ACgkQNN7p9ZyTYflBoAv/de2tzgcWzksE4OMN +aQggXbYtUxOmgLRy8Hrd+oAYuz9xozdsGFJoMdJlJ6i+XAGaGVUd1313isdkuS5a +C47pEpuLG1V9qMQzAbY0oHyB5h+lZZVnLz1y3TZZDgvLY57xrYP6hTrwKkxxQ5AT +kMhcxRBTRidxs9kJkx8jeeH+kYXeA3dS6Vk1IBiiDxJ/jb7qJfU+yb+hAbK3iBKh +/FNYQ2Qd/EeYq37PeIVdegMliKslbRX7fBs83P5ssy1Hci3T4l5ZKRppIRRdniD4 +cislFzAxCQefcVrF1Su2+cg+5tvYmSIH2OuY/rxJX6lpIPcnzI0hwTQNAQIEOmtd +UrOvJVRoLPCioi5G7pe1d5gssnyqrpILS+mFZvT+bSXFlfeMDC/eh6gz1/WIO9EN +qZ7/Tf23Fvt3shjg4EJ+IkwvjUZ+rTs0FPQ1xznjD82FPcSM6HX/jNpXnfwnYjju +kdZh4c3YFkkevPTmjTiV2m28vbl8V8mP3gjD3v8Tbjw0CbHGlQVYBF3zoc8BDADE +OhWcVTKIFUEx+NaAVEVwMk7z1F+61CBPjxLckA0izRP67AmqQ1ULulSF0mxI6xXC +1tc3mmyKkYYJg8pIVx+gwIZlBgkHFvzBFYIckuiALeYZstIi+3XzmO/bKgSWpsj1 +eD3qLjlao5hwz4cz9F6vco0Z+KXJc9l8EyHSjuzxyDmiGMDA29kZq1WJmUag2Ft6 +F67/RnFwpiYTVVwK9jrJUT3hqoBaoSobJNCFFM/atvDYgwjgmBhYKm936bkm0tTq +GOHIxnHqFu+qQ5e60UE2cxASw5j/CIW8h+nm/BdW6MokIYr50b47KvIrDWACwPnq +tsj3kInmHByTJ+pstDFxdoQlbELjehusPEmhhUKmbsL36MyT/q6CuitiBHOJpZi1 +s2w/0FTnAHhVxPLhxjd+E0DmPgrNJSdYrJtDo7nejUM46yMyLzB4gQQAt6HpSanv +a4U7UbJLZOPDunO4+svVFyOH9SDJwbqkr3kXDICCIgjLVJMotTkKxeZcQd8RMC0A +EQEAAQAL/iwdOM2IE8+nI5yF6kc4atHx5XEInirk1Iy+SAnA8ssPmr3PAc8+yuhT +j/vz1fdArog6f3DXLS6rz5vk/n1r5MbhcXVVuYLYBqOr36/n0RA8AV5mprpJmPdW +Oxok5Jovzb7ttNGoaal4XOWDqkwiVIUR9inQDglvm4W60WBCVH94uYg5E2BoLHMK +YzUHeergKRSWLXfjUM5389hl2Mb4Gzg2JPjOOYPmdo5apOw+RQpRFW0/bCf92X88 +rwmgyEizndhND6qREOQ/yt6TaY6jW5NMz0rXZuzzh8AN7QJ8Vnf+vl6yvhml/6Fv +PI/rjtjMIM6F4+eyQxyEBt70KOxa5zKbBkndr8vU9vBIF5+c62IwtD6jlFekUvU9 +G3RUZN4BecGp61FSovWYy7+Pct9s1NvI+704nQRi9j7HbYzXsY0UF4mjVUsY9nOW +0hYp5Z97Wpo8NZHS7uDFN6GG7AMWug7vwQiKawK70JtvfwPiNAwb7QEDlQY1cxlS +tGxptevCmwYA1arblASyI8C3PbQWfryuUfK/+xtknKe7TDapOL+wfnJBUA1WcKpO +jXDSPP+UShkIAueTCz3gNiQGN4zmbAL80QzHI605laceIYSC7hESNkT8wrjv3Mpt +J7Sle2bJfGHcV5J88G8kszt6uw0T/Gm84wjGP3jlWPJsklZAsoRpRcLi3zyRUYgY +6rsrHIgk0+ax4uUktqGterh8jpFn2IR4lwoeIBXwLlfnIVB/TQ85ahvlcFqnZAiU +5TfIX7Dx/yffBgDrGqYrkeXogJRZyk84BBkmOb2+6LKF+OicDowpJuaIB1xL3xeb +j8DL9C0HOFN4CZe7wDDditCPWCzTE/n1oIqrVpnm27hi9ylFeft5oL1eK2HyJ+VY +7CeLGRxEtMUkSij+/tYB4Kqdx+dZWUNRrzcrd75iwbyRRrV/ROCLLPt/CaoElGCu +LnZwlg/ZlAAI/Vs3oLZ5Q2JuGfBvH6eB/zJzxSPF1Hog2b5l0ogPhZR6cn0rccaN +yToeEdyQ94EimXMF/iszgPjfN+ZM7W926BXiCQfKsEu5NRpZgH3IYybBmqAkofgB +RqGisL+5WlOCfroDo34qaexq2AsmYQdypAgwFL2l/uNjsIfWu9+9Q5Aai2SBtO1A +oPTQGPzMQtUWTIFsk3+xpoocj75jzpOXlL14tpHl2yNpy9wittLFUXcFrAst1/AQ +/zNq9BASyZEYwM35VhXxy+//ZK6LgwI3MiSspQSB5K/eUNIxt+hVfV34iMlPtNQT +JaaeMU09NC3/pcxwQu1ItBdUZXN0IEtleSA8dGVzdEBleGFtcGxlPokB1AQTAQoA +PhYhBNTvLb7pe3ID1BWsdUf5wS+A6TmNBQJd86HPAhsDBQkDwmcABQsJCAcDBRUK +CQgLBRYCAwEAAh4BAheAAAoJEEf5wS+A6TmNKugL/1ECFLbAHiytuO0FhxAjLHRO +0HehBzO1IMiA9yh3t1SkuWwBElxfvXRIMKyVNnGYEW5kSxec0zL1OV3lj0K7BY5s +18YBY1Yr4YT4YNpQkRUMIemBxCbVYt5DUjdtyXmxDQuD24jolRfqsVJ2O+d+zHUm +iFHk13RgkhV+fGdHc7P40BPUHDAPPEZo73saKvudvT9lLG9iI3bhHZsCsi32E++i +NRxjTYVJI1fHT3E3EB75cM8XJhuPbw4tJ43gtHYR8OcpXGJCmLL4V6D3q866SZP1 +eiNPQk0a9PKmBSMzP9pFwYb5pfH+5u9zt0nq5dyV1H67yuCfgAplrtBFyFZJ/L00 +zhgkY7abLlO0hzvqKmmxLpfKYnx0PDw0WOvYnY1zn9dj+fymkLYIlo+za+SILEPE +GUqT/4TTDhm31AEKOTUohWNYNMqftfsydgBn7bwPixd7YxJHyhdwwrWmjrUHfHo3 +4l+BXo+jV9OixOeQZgfGaJHM5EWoAy2DrJ0ur8AUSJ0FWARd86HPAQwAtsY9YEeF +hwp2i0wopfTkhCbhZEdwx9rjXel0+Hxllh9FQ/+6cSL4ZrKC7rCcRE+jr1zOoFef +2OJfiY1Da2KawFZxdIJgbv3B9F4B6bSVN22LjxuOjPWeyNLjLSEnZ45ofXDYVRru +aQYvXR2GOzXlqytXDbPuSVAJX9l4kyZaW2zr6dMvaoUDlrPXcCmDZ3cCoWB4ocsA +AKBT5AMb/abxOLJ4qyWdk9FrQBKcT1L/dH1yDCcK0hw3ffR1yYZuKqQsTcAF/FIe +mf5m2KCB3LqLh2up5IqnbBW1QormeEuD6wG99dFmeubzSYhgj/tJCIXxXihLJw2J +6uv2StDbIZNFaKSk7JZcdb8Bp0Qfcw6FAcjjXiwUdi0w4dGMLUD32/twrfB5NnGi +bUb1bfvNMmjN3OREHcg9q8MpB/tebwUQ+Zx4r8bHgJnAoQvbRvxPddNg6t0OrI9o +iHFPkALAfZQMPbhVrY9GKpGEE8jIYGk1Xy3C0e7uxRUSlZVXE7b0ZfW5ABEBAAEA +C/4soEuFEgFyvuXBzicQmjIfaCTZKK5LRdEE8Yb7Utg05s6xMyPREuJGpOheIiYN +ccp7+zOCJ9LiECeWfLTM5+bz9kc+VMT55KByK2/ZIZvbTDZqiyZrmV8bFo6cSr+F +w9oUYrSXVvuGDhoLaLWJCHhaqjrXoCqaoN2hFwafGxqtvvL9BPDLV83QAnokKyan +4QF16Imbq2aFQKArCG1Rqey01LKsywLmABhpLQIYRiIUTbrGZ9P3CCeua71EpruI +UswKx0Fo2KUvggZ0CyjF0YSL6nr1iBStlrYbUxjmuUmwlxSq/t/5A7zZll0vMmya +wIyyNqeV8cPz5MTtQN5xLPWqry+KP688IhpVB8F9/7vzpTImyFyQTQK84T5FjHP7 +Z4XB61doY7Coedi2EQ0Nql+93l9rvuaweNBGA0M09RjqBfz8zv0yKbomcSUWXkSS +vZYIVQMjA4UjnPuWwbST5UavopQ4UyF4kXo5XTvsGgIUkORtbst+ze/0xHq30Pog +4nkGANK+jmIeMtkUGlz1zYleS/TVsxRakxB0Zxq2n/QL7Qwv2FUOjv9Ts1sfdbhz +UXF5RPSAQGPfFLyuUJrV1VWx+pFAnIm99wN6RdXxbIhusGXBzTeZJ0yfcsr+du+b +XoeJ0zcffjyc4dBMArwDsEado3AfwuIFCs3eCKEOD0CQkhT9BljSUxjKFw2nzveS +57muKXOfCf3hOAPkTIKYYv9it75SugoAg/PUy5MhqnbIDb7/YDrOqHm0l95nQAN8 +yL5+nQYA3gYQUoliZ2ybb0ALmxXAyyXnlRzanduPinb16ThLn5bqFRPXt2oKLdtB +GMuWhjmAimZU14akozv6bl2wtSnriTdoy0vA8+QUS5UJS9wOwgmqYItWa/6IBiNu +2gtrwJ4atZW5hbhrFSMNo1elZpt1rY07vfgZSYZfHGfIRUWlaFL1J5d6tuiz+uV5 +uUawfOy80pXBKxMCdsYv9NQ+9Uu+BnGqR3DQDq2CbBJHOS7j/akuhJy8bwvuXYyq +W1piZzrNBgDdRVVAp7mco51ZdyHH2hdFyL2Qpv9hLketkS0mkBVU9ETObZ6kuWbv +MQc5ob7i8vfK+0Pmg1L4H6kLp+DAiNoM+Zb+xxuQdkM3QB3MUzc//tOGJS8F92S3 +FOw96gg4rxUhOM6sDjxw+rb1SxlJkmvKpLwPqd4mu+tWTMd6MHomj9sdDLaf9Ast +wWK6uZ46+5DaHetIACDleI6HTX/e5mHUOPnY19rdBNooZOpDPZbh82YIN5RI47zq +Rf4hmWoy4Pnk1okBvAQYAQoAJhYhBNTvLb7pe3ID1BWsdUf5wS+A6TmNBQJd86HP +AhsMBQkDwmcAAAoJEEf5wS+A6TmNlMIL/0qAaWLVe502Agchpd4emt4ikq57clH2 +hmCIBl5UwSfJDqPOTMQ91ccbnWNuNeEnXdz4NJaWIEoJph6N1qLr9mS1Ox66591c +EHHHQgqm4jtNT/GP28gmsBNhmUBipJOn+gDM5ZPYTNpoZnZs/uoBVNM4mAkzDPpi +LM2vCiNDyHqlPr5DeIMZcJBJmlAbD7pM6Z0JnczKEg/54wuzzvp55qDdYWO6JzsU +VJ7qoBCgWI5OBi+ycOK3wUfK0r8gDRlHhJA5Q6B2tDINzERdW2ve0OC0No2TazlA +doY9s5T5OGbB9M7pHClAeOTtVYAkjpXDwu9uO0A2UJdcZTYTDpPth/V7plvRn3YG +iSW3FyYOYwH7EN9aasNyqxV8xib59hDO6KL+i6tFWs2spel8dNutPojk0ABQyge5 +Fm6WyRnbltHt8hB4jVBGZyHXLg7iw/AptBAuBFuUbRMbe9A0w3qP0tSuHbJdfyl8 +DZeT+S/3tXCwy1Jtoi7vcaoqUrjCGK6LAA== +=mcY/ +-----END PGP PRIVATE KEY BLOCK----- diff --git a/tests/data/test-signed-usable-repo/signed/Packages b/tests/data/test-signed-usable-repo/signed/Packages new file mode 100644 index 0000000..3ca29c9 --- /dev/null +++ b/tests/data/test-signed-usable-repo/signed/Packages @@ -0,0 +1,26 @@ +Package: signed-not-usable +Architecture: all +Version: 1.0 +Multi-Arch: foreign +Priority: optional +Section: misc +Maintainer: Julian Andres Klode +Installed-Size: 9 +Filename: ./signed-not-usable_1.0_all.deb +Size: 35 +MD5sum: f3034b91e355ba6046ff535ed044dcb5 +Description: Dummy package + +Package: signed-usable +Architecture: all +Version: 1.0 +Multi-Arch: foreign +Priority: optional +Section: misc +Maintainer: Julian Andres Klode +Installed-Size: 9 +Filename: ./signed-usable_1.0_all.deb +Size: 31 +MD5sum: 2d5166c110423c2d7c016642af4bd2eb +SHA256: 20edddf30a1bedf669f19caffa347299239b2a700ff428e33abc75e902f1d737 +Description: Dummy package diff --git a/tests/data/test-signed-usable-repo/signed/Release b/tests/data/test-signed-usable-repo/signed/Release new file mode 100644 index 0000000..135ce78 --- /dev/null +++ b/tests/data/test-signed-usable-repo/signed/Release @@ -0,0 +1,17 @@ +Date: Fri, 13 Dec 2019 16:11:05 +0000 +MD5Sum: + 21b1df48cfe01053dd2245763423cefb 668 Packages + 6715b0d77e7ea43fb252c78f1f826096 38 Release + 30432690119177a7f0c822c12f96e665 579 Sources +SHA1: + 910742c214560ce8ecdcb89c86fb1c0afa5a5373 668 Packages + 4a252d8c4ebc30d7330938a7dee06288877c4e3f 38 Release + 3147ec4b880bbb2cfa2a3f903b86d1dd2249488d 579 Sources +SHA256: + 445d75ee95443b89849b17f73ae434423d01c603f03c894a7be7851d36a5365d 668 Packages + c0ac431b6ea236c4d12e904b556bbb1f8d0abc733041cab4d65bfd3fd9704183 38 Release + 99140dde6468a8e073d8830faaf90e40c374957b98c1be446308dc8296ce5934 579 Sources +SHA512: + fdc2f7552c06ea197c8c40a44602218703a08d1b6a86f9319cc13a56ea8e7f7103c10aea6ee221b0bc88432ebb2651e3d2e5a93a3900fec5630db2e41684c57b 668 Packages + 5800d40647c79881b15119bbc576b12926151a2df37b96e18abc5fb04986663fa01867a83a1919225365b590a15e22032d12175eaf76336f167688c5a817ca13 38 Release + d0dd2a03687df03e4728219b9b149d514f8a734fcdeee8e45cb31229fc0f915eab634a50f934a60df42682e6dfbc65b962109bda616af642d6ee4cf821a877a1 579 Sources diff --git a/tests/data/test-signed-usable-repo/signed/Release.gpg b/tests/data/test-signed-usable-repo/signed/Release.gpg new file mode 100644 index 0000000..6b853bf --- /dev/null +++ b/tests/data/test-signed-usable-repo/signed/Release.gpg @@ -0,0 +1,14 @@ +-----BEGIN PGP SIGNATURE----- + +iQHFBAABCgAvFiEEJIBsPhVxGFtaHobENN7p9ZyTYfkFAl3zuBkRHHRlc3RAZXhh +bXBsZS5jb20ACgkQNN7p9ZyTYfkkrwv9HBgaZjSf3Bib9FH2alGZkBHKRcE2gWKf +d4PBXKLGgUutCy2g1Dn+FyBYB4OCf3H7ZsD6JFqrYSmLyGHAo+5QTMaPcRlVGoN8 +GL/fxJOEkRJruyC3k36toZTgXI/DGvSv1882syHTG0jOm8to95wiaQKDysTKOOTp +p1HJbX5DX+Wf2rXA/CL8KdH7rHzkIdhjdL4hucDw+JvNSywPEn0RSfvjtUS04d7G +Rw8H2PXyEnreO6OmMdwEmtImouIVxNZDFEEWUhdwujMnDtxM16uIIRLXa1sWQAzZ +M7RHNIhQHP1EvPuQRnKknacKUwchpg/IklxxruaRtjELSUMF5UOXJdnJFb3t6+pT +HBaW/c5piLfMsIV5U/bjQA76Ta4NccH5hah8x6+SjEZiP5RxSfQ9wpblYQeOmaUB +xi0tF6Ukqp5zfPi1RblziWZbN2/ty5zXpPOYbDT2geWo+8bVEhG6HwtHvpzuVymR +qtjOlCujLlkNZKG5jBHoOhuQjNPm+8RY +=wnyK +-----END PGP SIGNATURE----- diff --git a/tests/data/test-signed-usable-repo/signed/Sources b/tests/data/test-signed-usable-repo/signed/Sources new file mode 100644 index 0000000..52a8ee0 --- /dev/null +++ b/tests/data/test-signed-usable-repo/signed/Sources @@ -0,0 +1,21 @@ +Package: signed-not-usable +Format: 3.0 (native) +Binary: signed-not-usable +Architecture: any all +Version: 1.0 +Package-List: + signed-not-usable deb admin important arch=all +Files: + f2ae6d320641e8e241efcba02b5540fb 323 signed-not-usable_1.0.dsc + +Package: signed-usable +Format: 3.0 (native) +Binary: signed-usable +Architecture: any all +Version: 1.0 +Package-List: + signed-usable deb admin important arch=all +Files: + 491c58f65f493e838880a6ff30064c57 311 signed-usable_1.0.dsc +Checksums-Sha256: + 7a277156805101ce917dbb8d443d7087cc0ad333d25304f284976dba36339487 311 signed-usable_1.0.dsc diff --git a/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0.dsc b/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0.dsc new file mode 100644 index 0000000..2ebb766 --- /dev/null +++ b/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0.dsc @@ -0,0 +1,11 @@ +Format: 3.0 (native) +Source: signed-not-usable +Binary: signed-not-usable +Architecture: any all +Version: 1.0 +Package-List: + signed-not-usable deb admin important arch=all +Checksums-Sha256: + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 test.tar.xz +Files: + d41d8cd98f00b204e9800998ecf8427e 0 test.tar.xz diff --git a/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0_all.deb b/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0_all.deb new file mode 100644 index 0000000..e098ca5 --- /dev/null +++ b/tests/data/test-signed-usable-repo/signed/signed-not-usable_1.0_all.deb @@ -0,0 +1 @@ +i am signed-not-usable_1.0_all.deb diff --git a/tests/data/test-signed-usable-repo/signed/signed-usable_1.0.dsc b/tests/data/test-signed-usable-repo/signed/signed-usable_1.0.dsc new file mode 100644 index 0000000..04b4f64 --- /dev/null +++ b/tests/data/test-signed-usable-repo/signed/signed-usable_1.0.dsc @@ -0,0 +1,11 @@ +Format: 3.0 (native) +Source: signed-usable +Binary: signed-usable +Architecture: any all +Version: 1.0 +Package-List: + signed-usable deb admin important arch=all +Checksums-Sha256: + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 test.tar.xz +Files: + d41d8cd98f00b204e9800998ecf8427e 0 test.tar.xz diff --git a/tests/data/test-signed-usable-repo/signed/signed-usable_1.0_all.deb b/tests/data/test-signed-usable-repo/signed/signed-usable_1.0_all.deb new file mode 100644 index 0000000..cd58831 --- /dev/null +++ b/tests/data/test-signed-usable-repo/signed/signed-usable_1.0_all.deb @@ -0,0 +1 @@ +i am signed-usable_1.0_all.deb diff --git a/tests/data/test-signed-usable-repo/unsigned/Packages b/tests/data/test-signed-usable-repo/unsigned/Packages new file mode 100644 index 0000000..22f4fff --- /dev/null +++ b/tests/data/test-signed-usable-repo/unsigned/Packages @@ -0,0 +1,26 @@ +Package: unsigned-unusable +Architecture: all +Version: 1.0 +Multi-Arch: foreign +Priority: optional +Section: misc +Maintainer: Julian Andres Klode +Installed-Size: 9 +Filename: ./unsigned-unusable_1.0_all.deb +Size: 35 +MD5sum: 368e155b22e873eb71ae43b80379c0ea +Description: Dummy package + +Package: unsigned-usable +Architecture: all +Version: 1.0 +Multi-Arch: foreign +Priority: optional +Section: misc +Maintainer: Julian Andres Klode +Installed-Size: 9 +Filename: ./unsigned-usable_1.0_all.deb +Size: 33 +MD5sum: 0a0bb7636879ae8a38b679bc3d09b627 +SHA256: ddc71095223eb039cce782e813782b917502e0f3c99a1142ea2d92b34737a243 +Description: Dummy package diff --git a/tests/data/test-signed-usable-repo/unsigned/Release b/tests/data/test-signed-usable-repo/unsigned/Release new file mode 100644 index 0000000..18552a2 --- /dev/null +++ b/tests/data/test-signed-usable-repo/unsigned/Release @@ -0,0 +1,17 @@ +Date: Fri, 13 Dec 2019 16:04:58 +0000 +MD5Sum: + dd9db6eb770d950241fc5dfd1b94d4c5 672 Packages + 808b5c1ee28bdae1ffe98a8ee632a4ff 38 Release + bb3efd66e75fa995971ddf8d3bdcd6cb 592 Sources +SHA1: + 4b83e0112704ce4aa20d5833dfad0617404cb48f 672 Packages + 9cba73573f2824f5691293802046a707d1493cdf 38 Release + 4e4a503ec704e11c963c042f44a3ad9da7f30b88 592 Sources +SHA256: + e7a1760be467c66c570e3a5feddfb8d82a14cb4a201382353e4d9bf4c8fb530a 672 Packages + b7efc8e49608e74fefd10f93081843b66200cf9b3d12af7e7772138d8d9fd514 38 Release + f1bea3fd5e27e0a2b606ef23690a611b6a1b60baf42284d5469431dfae4c316a 592 Sources +SHA512: + 4d951a837afed5be1aa89e594587b34f533408b28e4f3b0ffd2c69e5edf45873e24ace59126b12c8f83734ca5daa1d901f2f51170ac325b2787b3674e7226d93 672 Packages + 31d2d8013ee14aa414abf831819f2896f2d9c323fbfcfbc24bf7d602e1855a97ae049125397afd909e8a78aa0c016469731742f7dded416680fced49cce4b088 38 Release + e476cf4357f0f5ec00529dd96b782d9ed52e94db06020ad64ec976f4be6f3783151267fd9916857bedd1c3b693a338f53501d09200a0834c004da54f5acbfca0 592 Sources diff --git a/tests/data/test-signed-usable-repo/unsigned/Sources b/tests/data/test-signed-usable-repo/unsigned/Sources new file mode 100644 index 0000000..9eaf48b --- /dev/null +++ b/tests/data/test-signed-usable-repo/unsigned/Sources @@ -0,0 +1,22 @@ +Package: unsigned-unusable +Format: 3.0 (native) +Binary: unsigned-unusable +Architecture: any all +Version: 1.0 +Package-List: + unsigned-unusable deb admin important arch=all +Files: + c9c8d679a878ca08faca12baf5e2398d 323 unsigned-not-usable_1.0.dsc + + +Package: unsigned-usable +Format: 3.0 (native) +Binary: unsigned-usable +Architecture: any all +Version: 1.0 +Package-List: + unsigned-usable deb admin important arch=all +Files: + 864f4834dabbd30e6472902b000d7a76 317 unsigned-usable_1.0.dsc +Checksums-Sha256: + eb6c1ebc468b4687bb6bffe25afd5ab1e1812beb9577fac7560396bcb7775939 317 unsigned-usable_1.0.dsc diff --git a/tests/data/test-signed-usable-repo/unsigned/unsigned-not-usable_1.0.dsc b/tests/data/test-signed-usable-repo/unsigned/unsigned-not-usable_1.0.dsc new file mode 100644 index 0000000..f8156c1 --- /dev/null +++ b/tests/data/test-signed-usable-repo/unsigned/unsigned-not-usable_1.0.dsc @@ -0,0 +1,11 @@ +Format: 3.0 (native) +Source: unsigned-unusable +Binary: unsigned-unusable +Architecture: any all +Version: 1.0 +Package-List: + unsigned-unusable deb admin important arch=all +Checksums-Sha256: + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 test.tar.xz +Files: + d41d8cd98f00b204e9800998ecf8427e 0 test.tar.xz diff --git a/tests/data/test-signed-usable-repo/unsigned/unsigned-unusable_1.0_all.deb b/tests/data/test-signed-usable-repo/unsigned/unsigned-unusable_1.0_all.deb new file mode 100644 index 0000000..7465ec1 --- /dev/null +++ b/tests/data/test-signed-usable-repo/unsigned/unsigned-unusable_1.0_all.deb @@ -0,0 +1 @@ +i am unsigned-unusable_1.0_all.deb diff --git a/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0.dsc b/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0.dsc new file mode 100644 index 0000000..a625bb6 --- /dev/null +++ b/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0.dsc @@ -0,0 +1,11 @@ +Format: 3.0 (native) +Source: unsigned-usable +Binary: unsigned-usable +Architecture: any all +Version: 1.0 +Package-List: + unsigned-usable deb admin important arch=all +Checksums-Sha256: + e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 0 test.tar.xz +Files: + d41d8cd98f00b204e9800998ecf8427e 0 test.tar.xz diff --git a/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0_all.deb b/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0_all.deb new file mode 100644 index 0000000..2f748b0 --- /dev/null +++ b/tests/data/test-signed-usable-repo/unsigned/unsigned-usable_1.0_all.deb @@ -0,0 +1 @@ +i am unsigned-usable_1.0_all.deb diff --git a/tests/data/test-source-repo/Sources b/tests/data/test-source-repo/Sources new file mode 100644 index 0000000..4758871 --- /dev/null +++ b/tests/data/test-source-repo/Sources @@ -0,0 +1,25 @@ +Package: dh-autoreconf +Format: 3.0 (native) +Binary: dh-autoreconf +Architecture: all +Version: 16 +Maintainer: Julian Andres Klode +Standards-Version: 4.1.1 +Build-Depends: debhelper (>= 9) +Vcs-Browser: https://anonscm.debian.org/git/collab-maint/dh-autoreconf.git +Vcs-Git: https://anonscm.debian.org/git/collab-maint/dh-autoreconf.git +Package-List: + dh-autoreconf deb devel optional arch=all +Files: + 6576a28fe1918ce10bd31543ba545901 1578 dh-autoreconf_16.dsc + 302c8bf43db02412e3f2197fd0f2ee0f 7372 dh-autoreconf_16.tar.xz +Checksums-Sha1: + c9bf7a920013021dad5fbd898dfd5a79c7a150f9 1578 dh-autoreconf_16.dsc + 58459600164398ad6807ddd877a6f814c799c62c 7372 dh-autoreconf_16.tar.xz +Checksums-Sha256: + 1c1b2ab5f1ae5496bd50dbb3c30e9b7d181a06c8d02ee8d7e9c35ed6f2a69b5f 1578 dh-autoreconf_16.dsc + 5c6a6a362907327bec77a867ff3fd0eceba8015d1b881b48275aff7e4ce0f629 7372 dh-autoreconf_16.tar.xz +Checksums-Sha512: + 4b1a3299f2a8b01b0c75db97fd16cb39919949c74d19ea6cf28e1bbd4891d3515b3e2b90b96a64df665cebf6d95409e704e670909ae91fcfe92409ee1339bffc 1578 dh-autoreconf_16.dsc + 10448dd179ec12bf4310a9a514110a85f56e51893aa36a97ac3a6f8d7ce99d099e62cfdb78e271e2d94431e8832da0f643de821b6643b80e3f0b0f5d682cf9a9 7372 dh-autoreconf_16.tar.xz + diff --git a/tests/data/test_debs/data-tar-broken.deb b/tests/data/test_debs/data-tar-broken.deb new file mode 100644 index 0000000..4fd42e0 Binary files /dev/null and b/tests/data/test_debs/data-tar-broken.deb differ diff --git a/tests/data/test_debs/data-tar-xz.deb b/tests/data/test_debs/data-tar-xz.deb new file mode 100644 index 0000000..9dd4d67 Binary files /dev/null and b/tests/data/test_debs/data-tar-xz.deb differ diff --git a/tests/data/test_debs/data-tar.deb b/tests/data/test_debs/data-tar.deb new file mode 100644 index 0000000..d8e4a98 Binary files /dev/null and b/tests/data/test_debs/data-tar.deb differ diff --git a/tests/data/test_debs/etc/apt/sources.list b/tests/data/test_debs/etc/apt/sources.list new file mode 100644 index 0000000..3cc95c7 --- /dev/null +++ b/tests/data/test_debs/etc/apt/sources.list @@ -0,0 +1 @@ +deb http://archive.ubuntu.com/ubuntu maverick main diff --git a/tests/data/test_debs/gdebi-test1.deb b/tests/data/test_debs/gdebi-test1.deb new file mode 100644 index 0000000..ea9991a Binary files /dev/null and b/tests/data/test_debs/gdebi-test1.deb differ diff --git a/tests/data/test_debs/gdebi-test10.deb b/tests/data/test_debs/gdebi-test10.deb new file mode 100644 index 0000000..ca43ace Binary files /dev/null and b/tests/data/test_debs/gdebi-test10.deb differ diff --git a/tests/data/test_debs/gdebi-test11.deb b/tests/data/test_debs/gdebi-test11.deb new file mode 100644 index 0000000..af9b441 Binary files /dev/null and b/tests/data/test_debs/gdebi-test11.deb differ diff --git a/tests/data/test_debs/gdebi-test12.deb b/tests/data/test_debs/gdebi-test12.deb new file mode 100644 index 0000000..36544cc Binary files /dev/null and b/tests/data/test_debs/gdebi-test12.deb differ diff --git a/tests/data/test_debs/gdebi-test13.deb b/tests/data/test_debs/gdebi-test13.deb new file mode 100644 index 0000000..4e7a828 Binary files /dev/null and b/tests/data/test_debs/gdebi-test13.deb differ diff --git a/tests/data/test_debs/gdebi-test2.deb b/tests/data/test_debs/gdebi-test2.deb new file mode 100644 index 0000000..307ac68 Binary files /dev/null and b/tests/data/test_debs/gdebi-test2.deb differ diff --git a/tests/data/test_debs/gdebi-test3.deb b/tests/data/test_debs/gdebi-test3.deb new file mode 100644 index 0000000..436b925 Binary files /dev/null and b/tests/data/test_debs/gdebi-test3.deb differ diff --git a/tests/data/test_debs/gdebi-test4.deb b/tests/data/test_debs/gdebi-test4.deb new file mode 100644 index 0000000..9eb92d1 Binary files /dev/null and b/tests/data/test_debs/gdebi-test4.deb differ diff --git a/tests/data/test_debs/gdebi-test5.deb b/tests/data/test_debs/gdebi-test5.deb new file mode 100644 index 0000000..0c98c03 Binary files /dev/null and b/tests/data/test_debs/gdebi-test5.deb differ diff --git a/tests/data/test_debs/gdebi-test6.deb b/tests/data/test_debs/gdebi-test6.deb new file mode 100644 index 0000000..8ceacad Binary files /dev/null and b/tests/data/test_debs/gdebi-test6.deb differ diff --git a/tests/data/test_debs/gdebi-test7.deb b/tests/data/test_debs/gdebi-test7.deb new file mode 100644 index 0000000..c041499 Binary files /dev/null and b/tests/data/test_debs/gdebi-test7.deb differ diff --git a/tests/data/test_debs/gdebi-test8.deb b/tests/data/test_debs/gdebi-test8.deb new file mode 100644 index 0000000..439f8ca Binary files /dev/null and b/tests/data/test_debs/gdebi-test8.deb differ diff --git a/tests/data/test_debs/gdebi-test9.deb b/tests/data/test_debs/gdebi-test9.deb new file mode 100644 index 0000000..9901d90 Binary files /dev/null and b/tests/data/test_debs/gdebi-test9.deb differ diff --git a/tests/data/test_debs/hello_2.5-1.dsc b/tests/data/test_debs/hello_2.5-1.dsc new file mode 100644 index 0000000..d00db52 --- /dev/null +++ b/tests/data/test_debs/hello_2.5-1.dsc @@ -0,0 +1,34 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +Format: 1.0 +Source: hello +Binary: hello, bello, + cello +Architecture: any +Version: 2.5-1 +Maintainer: Santiago Vila +Homepage: http://www.gnu.org/software/hello +Standards-Version: 3.8.4 +Build-Depends: autotools-dev +Checksums-Sha1: + dfaf92bfc8144141bcd5ffb4a30777cd57501bfa 582535 hello_2.5.orig.tar.gz + a98ab19072b35295ded3560721662131933f7c05 5965 hello_2.5-1.diff.gz +Checksums-Sha256: + 22934a7d3a62f247ce3b5a77a2c7f7dd095ad8aef305efa2d0d15e0fef31c446 582535 hello_2.5.orig.tar.gz + c2f17c08a6a94bdab4f4316beb4687e8468de03a5162f1d694a0bab4b90e5962 5965 hello_2.5-1.diff.gz +Files: + cf4b73d837692b93676ccd723bf6f797 582535 hello_2.5.orig.tar.gz + fa6c41ce60b975294781ed00d67f32fe 5965 hello_2.5-1.diff.gz + +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.10 (GNU/Linux) + +iQEcBAEBCAAGBQJLeDJTAAoJEEHOfwufG4syQSAH/0S9vYKRbs71bfGNmKTmRQy6 +TJM1oj3hdjJoE9HBvCBoBhRSB7l5Iz+TDVyvKTcFOnXTWrZfhnNRCoErtOxP8Z0R +MOEeLDTPf3JEvpwaRbfzngp+dRkAXTJSI+equqOvj4jjPd1lrNegWtwTF6VIlXAX +5s+onfBp29/MesxzTGAdviobMYCdazmi2XceC+t5ZEJzEsMMPO6i/v22SrvE/Jkg +LiD/U6gea3/1dovsUY6I7/VyzMhHgdcuUW4dzovr2daLwE+uRp9R90XDtKN5aWUM +oBzk8vBIsw/3EV5kjCKdMtqFGdHBjn4nTKvyoXmJ1SvEzeEd21WvLsBFpcJVKaw= +=YMqG +-----END PGP SIGNATURE----- diff --git a/tests/data/test_debs/impossible-build-depends_2.5-1.dsc b/tests/data/test_debs/impossible-build-depends_2.5-1.dsc new file mode 100644 index 0000000..7f7364a --- /dev/null +++ b/tests/data/test_debs/impossible-build-depends_2.5-1.dsc @@ -0,0 +1,33 @@ +-----BEGIN PGP SIGNED MESSAGE----- +Hash: SHA256 + +Format: 1.0 +Source: hello +Binary: hello +Architecture: any +Version: 2.5-1 +Maintainer: Santiago Vila +Homepage: http://www.gnu.org/software/hello +Standards-Version: 3.8.4 +Build-Depends: debhelper (>> 101) +Checksums-Sha1: + dfaf92bfc8144141bcd5ffb4a30777cd57501bfa 582535 hello_2.5.orig.tar.gz + a98ab19072b35295ded3560721662131933f7c05 5965 hello_2.5-1.diff.gz +Checksums-Sha256: + 22934a7d3a62f247ce3b5a77a2c7f7dd095ad8aef305efa2d0d15e0fef31c446 582535 hello_2.5.orig.tar.gz + c2f17c08a6a94bdab4f4316beb4687e8468de03a5162f1d694a0bab4b90e5962 5965 hello_2.5-1.diff.gz +Files: + cf4b73d837692b93676ccd723bf6f797 582535 hello_2.5.orig.tar.gz + fa6c41ce60b975294781ed00d67f32fe 5965 hello_2.5-1.diff.gz + +-----BEGIN PGP SIGNATURE----- +Version: GnuPG v1.4.10 (GNU/Linux) + +iQEcBAEBCAAGBQJLeDJTAAoJEEHOfwufG4syQSAH/0S9vYKRbs71bfGNmKTmRQy6 +TJM1oj3hdjJoE9HBvCBoBhRSB7l5Iz+TDVyvKTcFOnXTWrZfhnNRCoErtOxP8Z0R +MOEeLDTPf3JEvpwaRbfzngp+dRkAXTJSI+equqOvj4jjPd1lrNegWtwTF6VIlXAX +5s+onfBp29/MesxzTGAdviobMYCdazmi2XceC+t5ZEJzEsMMPO6i/v22SrvE/Jkg +LiD/U6gea3/1dovsUY6I7/VyzMhHgdcuUW4dzovr2daLwE+uRp9R90XDtKN5aWUM +oBzk8vBIsw/3EV5kjCKdMtqFGdHBjn4nTKvyoXmJ1SvEzeEd21WvLsBFpcJVKaw= +=YMqG +-----END PGP SIGNATURE----- diff --git a/tests/data/test_debs/large-package-content_1.0_all.deb b/tests/data/test_debs/large-package-content_1.0_all.deb new file mode 100644 index 0000000..56bdce3 Binary files /dev/null and b/tests/data/test_debs/large-package-content_1.0_all.deb differ diff --git a/tests/data/test_debs/multiarch-test1_i386.deb b/tests/data/test_debs/multiarch-test1_i386.deb new file mode 100644 index 0000000..439a9f4 Binary files /dev/null and b/tests/data/test_debs/multiarch-test1_i386.deb differ diff --git a/tests/data/test_debs/testdep-allowed-any_1.0-1_i386.deb b/tests/data/test_debs/testdep-allowed-any_1.0-1_i386.deb new file mode 100644 index 0000000..c56f819 Binary files /dev/null and b/tests/data/test_debs/testdep-allowed-any_1.0-1_i386.deb differ diff --git a/tests/data/test_debs/testdep-same-arch_1.0-1_i386.deb b/tests/data/test_debs/testdep-same-arch_1.0-1_i386.deb new file mode 100644 index 0000000..872f3b6 Binary files /dev/null and b/tests/data/test_debs/testdep-same-arch_1.0-1_i386.deb differ diff --git a/tests/data/test_debs/utf8-package_1.0-1_all.deb b/tests/data/test_debs/utf8-package_1.0-1_all.deb new file mode 100644 index 0000000..e0339c2 Binary files /dev/null and b/tests/data/test_debs/utf8-package_1.0-1_all.deb differ diff --git a/tests/data/test_debs/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_maverick_main_binary-i386_Packages b/tests/data/test_debs/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_maverick_main_binary-i386_Packages new file mode 100644 index 0000000..b3b30d0 --- /dev/null +++ b/tests/data/test_debs/var/lib/apt/lists/archive.ubuntu.com_ubuntu_dists_maverick_main_binary-i386_Packages @@ -0,0 +1,31 @@ +Package: autotools-dev +Priority: optional +Section: devel +Installed-Size: 216 +Maintainer: Ubuntu Developers +Original-Maintainer: Henrique de Moraes Holschuh +Architecture: all +Version: 20100122.1 +Filename: pool/main/a/autotools-dev/autotools-dev_20100122.1_all.deb +Size: 70700 +MD5sum: dc25cef0035a3fc7c64b9f2eeddac5d2 +SHA1: 40bcffb6bc2ec7aeaae747c300a0ad70ef3bb38c +SHA256: 290aaf1d5d5a6c560a128b6fe5557fe981ebb85e105410f3bca2e468ce54aaac +Description: Update infrastructure for config.{guess,sub} files + This package installs an up-to-date version of config.guess and + config.sub, used by the automake and libtool packages. It provides + the canonical copy of those files for other packages as well. + . + It also documents in /usr/share/doc/autotools-dev/README.Debian.gz + best practices and guidelines for using autoconf, automake and + friends on Debian packages. This is a must-read for any developers + packaging software that uses the GNU autotools, or GNU gettext. + . + Additionally this package provides seamless integration into Debhelper + or CDBS, allowing maintainers to easily update config.{guess,sub} files + in their packages. +Enhances: cdbs, debhelper +Homepage: http://savannah.gnu.org/projects/config/ +Bugs: https://bugs.launchpad.net/ubuntu/+filebug +Origin: Ubuntu +Supported: 18m diff --git a/tests/data/test_debs/var/lib/dpkg/status b/tests/data/test_debs/var/lib/dpkg/status new file mode 100644 index 0000000..5c2c48a --- /dev/null +++ b/tests/data/test_debs/var/lib/dpkg/status @@ -0,0 +1,92 @@ +Package: apt +Status: install ok installed +Priority: important +Section: admin +Installed-Size: 5456 +Maintainer: APT Development Team +Architecture: i386 +Version: 0.7.25.3 +Replaces: libapt-pkg-dev (<< 0.3.7), libapt-pkg-doc (<< 0.3.7) +Provides: libapt-pkg-libc6.10-6-4.8 +Description: Advanced front-end for dpkg + This is Debian's next generation front-end for the dpkg package manager. + It provides the apt-get utility and APT dselect method that provides a + simpler, safer way to install and upgrade packages. + . + APT features complete installation ordering, multiple source capability + and several other unique features, see the Users Guide in apt-doc. + +Package: postfix +Status: install ok installed +Priority: extra +Section: mail +Installed-Size: 3488 +Maintainer: LaMont Jones +Architecture: i386 +Version: 2.7.0-1 +Replaces: mail-transport-agent, postfix-tls +Provides: default-mta, mail-transport-agent, postfix-tls +Recommends: python +Conflicts: libnss-db (<< 2.2-3), mail-transport-agent, postfix-tls, smail +Description: High-performance mail transport agent + Postfix is Wietse Venema's mail transport agent that started life as an + alternative to the widely-used Sendmail program. Postfix attempts to + be fast, easy to administer, and secure, while at the same time being + sendmail compatible enough to not upset existing users. Thus, the outside + has a sendmail-ish flavor, but the inside is completely different. + +Package: debconf +Status: install ok installed +Priority: important +Section: admin +Installed-Size: 924 +Maintainer: Debconf Developers +Architecture: all +Version: 1.5.28 +Replaces: debconf-tiny +Provides: debconf-2.0 +Recommends: apt-utils (>= 0.5.1) +Conflicts: apt (<< 0.3.12.1), cdebconf (<< 0.96), debconf-tiny, debconf-utils (<< 1.3.22), dialog (<< 0.9b-20020814-1), menu (<= 2.1.3-1), whiptail (<< 0.51.4-11), whiptail-utf8 (<= 0.50.17-13) +Description: Debian configuration management system + Debconf is a configuration management system for debian packages. Packages + use Debconf to ask questions when they are installed. +Python-Version: 2.6, 3.1 + +Package: testdep-same +Status: install ok installed +Source: testdep +Version: 1.0-1 +Architecture: amd64 +Maintainer: Francois Gouget +Installed-Size: 25 +Provides: testdep-virtual-same +Section: unknown +Priority: extra +Multi-Arch: same +Description: Multi-arch = same package, no dependency + This is a multiarch package that can only satisfy dependencies for the same + architecture. But multiple instances of this package can be co-installed, + one for each architecture. + . + Library and development packages typically fall into this category. + +Package: testdep-allowed +Status: install ok installed +Source: testdep +Version: 1.0-1 +Architecture: amd64 +Maintainer: Francois Gouget +Installed-Size: 25 +Provides: testdep-virtual-allowed +Section: unknown +Priority: extra +Multi-Arch: allowed +Description: Multi-arch = allowed package, no dependency + This is a multiarch package. By default it can only satisfy dependencies for + packages of the same architecture but that can be changed with ':any' + dependencies. + . + It can only be installed for one architecture at a time. Trying to install the + same package for another architecture will remove the first one. + . + Packages providing tools or shells typically fall into this category. diff --git a/tests/fakeroot-apt-key b/tests/fakeroot-apt-key new file mode 100755 index 0000000..997161a --- /dev/null +++ b/tests/fakeroot-apt-key @@ -0,0 +1,2 @@ +#!/bin/sh +exec fakeroot /usr/bin/apt-key $* diff --git a/tests/helper_install_progress_run.py b/tests/helper_install_progress_run.py new file mode 100755 index 0000000..02e601d --- /dev/null +++ b/tests/helper_install_progress_run.py @@ -0,0 +1,15 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2019 Colomban Wendling +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Helper checking argv[1] is a valid, writable, file descriptor""" + +import os +from sys import argv + +assert len(argv) == 2 +with os.fdopen(int(argv[1]), "w") as f: + assert f.write("test") == 4 diff --git a/tests/old/__init__.py b/tests/old/__init__.py new file mode 100644 index 0000000..5311641 --- /dev/null +++ b/tests/old/__init__.py @@ -0,0 +1,11 @@ +import os +import unittest + +if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + print(os.getcwd()) + + for path in os.listdir("."): + if path.endswith(".py"): + exec("from %s import *" % path[:-3]) + unittest.main() diff --git a/tests/old/apt-test.py b/tests/old/apt-test.py new file mode 100644 index 0000000..8c66aeb --- /dev/null +++ b/tests/old/apt-test.py @@ -0,0 +1,27 @@ +import warnings + +warnings.filterwarnings("ignore", "apt API not stable yet", FutureWarning) +import apt + +if __name__ == "__main__": + progress = apt.progress.OpTextProgress() + cache = apt.Cache(progress) + print(cache) + for pkg in cache: + if pkg.is_upgradable: + pkg.mark_install() + for pkg in cache.get_changes(): + # print pkg.name() + pass + print("Broken: %s " % cache._depcache.broken_count) + print("inst_count: %s " % cache._depcache.inst_count) + + # get a new cache + cache = apt.Cache(progress) + for name in cache.keys(): + import random + + if random.randint(0, 1) == 1: + cache[name].mark_delete() + print("Broken: %s " % cache._depcache.broken_count) + print("del_count: %s " % cache._depcache.del_count) diff --git a/tests/old/cache.py b/tests/old/cache.py new file mode 100644 index 0000000..3f4aa0c --- /dev/null +++ b/tests/old/cache.py @@ -0,0 +1,51 @@ +#!/usr/bin/python3 +# +# Test for the pkgCache code +# + +import sys + +import apt_pkg + + +def main(): + apt_pkg.init() + cache = apt_pkg.Cache() + depcache = apt_pkg.DepCache(cache) + depcache.init() + i = 0 + all = cache.package_count + print("Running Cache test on all packages:") + # first, get all pkgs + for pkg in cache.packages: + i += 1 + pkg.name + # then get each version + for ver in pkg.version_list: + # get some version information + ver.file_list + ver.ver_str + ver.arch + ver.depends_listStr + dl = ver.depends_list + # get all dependencies (a dict of string->list, + # e.g. "depends:" -> [ver1,ver2,..] + for dep in dl.keys(): + # get the list of each dependency object + for depVerList in dl[dep]: + for z in depVerList: + # get all TargetVersions of + # the dependency object + for j in z.all_targets(): + j.file_list + ver.ver_str + ver.arch + ver.depends_listStr + j = ver.depends_list + + print("\r%i/%i=%.3f%% " % (i, all, (float(i) / float(all) * 100))) + + +if __name__ == "__main__": + main() + sys.exit(0) diff --git a/tests/old/depcache.py b/tests/old/depcache.py new file mode 100644 index 0000000..81ca574 --- /dev/null +++ b/tests/old/depcache.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python2.4 +# +# Test for the DepCache code +# + +import sys + +import apt_pkg + + +def main(): + apt_pkg.init() + cache = apt_pkg.Cache() + depcache = apt_pkg.DepCache(cache) + depcache.init() + i = 0 + all = cache.package_count + print("Running DepCache test on all packages") + print("(trying to install each and then mark it keep again):") + # first, get all pkgs + for pkg in cache.packages: + i += 1 + x = pkg.name + # then get each version + ver = depcache.get_candidate_ver(pkg) + if ver is not None: + depcache.mark_install(pkg) + if depcache.inst_count == 0: + if depcache.is_upgradable(pkg): + print("Error marking %s for install" % x) + for p in cache.packages: + if depcache.marked_install(p): + depcache.mark_keep(p) + if depcache.inst_count != 0: + print( + "Error undoing the selection for %s (inst_count: %s)" + % (x, depcache.inst_count) + ) + print("\r%i/%i=%.3f%% " % (i, all, (float(i) / float(all) * 100))) + + print() + print("Trying upgrade:") + depcache.upgrade() + print("To install: %s " % depcache.inst_count) + print("To remove: %s " % depcache.del_count) + print("Kept back: %s " % depcache.keep_count) + + print("Trying DistUpgrade:") + depcache.upgrade(True) + print("To install: %s " % depcache.inst_count) + print("To remove: %s " % depcache.del_count) + print("Kept back: %s " % depcache.keep_count) + + +if __name__ == "__main__": + main() + sys.exit(0) diff --git a/tests/old/lock.py b/tests/old/lock.py new file mode 100644 index 0000000..c09983c --- /dev/null +++ b/tests/old/lock.py @@ -0,0 +1,47 @@ +#!/usr/bin/env python2.4 +# +# Test for the pkgCache code +# + +import os +import sys + +import apt_pkg + +if __name__ == "__main__": + lock = "/tmp/test.lck" + + apt_pkg.init() + + # system-lock + apt_pkg.pkgsystem_lock() + + pid = os.fork() + if pid == 0: + try: + apt_pkg.pkgsystem_lock() + except SystemError as s: + print("Can't get lock: (error text:\n%s)" % s) + sys.exit(0) + + apt_pkg.pkgsystem_unlock() + + # low-level lock + fd = apt_pkg.get_lock(lock, True) + print("Lockfile fd: %s" % fd) + + # try to get lock without error flag + pid = os.fork() + if pid == 0: + # child + fd = apt_pkg.get_lock(lock, False) + print("Lockfile fd (child): %s" % fd) + sys.exit(0) + + # try to get lock with error flag + pid = os.fork() + if pid == 0: + # child + fd = apt_pkg.get_lock(lock, True) + print("Lockfile fd (child): %s" % fd) + sys.exit(0) diff --git a/tests/old/memleak.py b/tests/old/memleak.py new file mode 100644 index 0000000..44b123e --- /dev/null +++ b/tests/old/memleak.py @@ -0,0 +1,45 @@ +#!/usr/bin/python3 + +import gc +import time + +import apt_pkg + +import apt + +cache = apt.Cache() + +# memleak +for i in range(100): + cache.open(None) + print(cache["apt"].name) + time.sleep(1) + gc.collect() + f = open("%s" % i, "w") + for obj in gc.get_objects(): + f.write("%s\n" % str(obj)) + f.close() + +# memleak +# for i in range(100): +# cache = apt.Cache() +# time.sleep(1) +# cache = None +# gc.collect() + +# no memleak, but more or less the apt.Cache.open() code +for i in range(100): + cache = apt_pkg.Cache() + depcache = apt_pkg.DepCache(cache) + records = apt_pkg.PackageRecords(cache) + list = apt_pkg.SourceList() + list.read_main_list() + dict = {} + for pkg in cache.packages: + if len(pkg.version_list) > 0: + dict[pkg.name] = apt.package(cache, depcache, records, list, None, pkg) + + print(cache["apt"]) + time.sleep(1) + + gc.collect() diff --git a/tests/old/pkgproblemresolver.py b/tests/old/pkgproblemresolver.py new file mode 100644 index 0000000..89190cf --- /dev/null +++ b/tests/old/pkgproblemresolver.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python2.4 +# +# Test for the DepCache code +# + +import sys + +import apt_pkg + + +def main(): + apt_pkg.init() + cache = apt_pkg.Cache() + depcache = apt_pkg.DepCache(cache) + depcache.init() + i = 0 + all = cache.package_count + print("Running DepCache test on all packages") + print("(trying to install each and then mark it keep again):") + # first, get all pkgs + for pkg in cache.packages: + i += 1 + x = pkg.name + # then get each version + ver = depcache.get_candidate_ver(pkg) + if ver is not None: + depcache.mark_install(pkg) + if depcache.broken_count > 0: + fixer = apt_pkg.ProblemResolver(depcache) + fixer.clear(pkg) + fixer.protect(pkg) + # we first try to resolve the problem + # with the package that should be installed + # protected + try: + fixer.resolve(True) + except SystemError: + # the pkg seems to be broken, the + # returns a exception + fixer.clear(pkg) + fixer.resolve(True) + if not depcache.marked_install(pkg): + print("broken in archive: %s " % pkg.name) + fixer = None + if depcache.inst_count == 0: + if depcache.is_upgradable(pkg): + print("Error marking %s for install" % x) + for p in cache.packages: + if depcache.marked_install(p) or depcache.marked_upgrade(p): + depcache.mark_keep(p) + if depcache.inst_count != 0: + print("Error undoing the selection for %s" % x) + print("\r%i/%i=%.3f%% " % (i, all, (float(i) / float(all) * 100))) + + print() + print("Trying upgrade:") + depcache.upgrade() + print("To install: %s " % depcache.inst_count) + print("To remove: %s " % depcache.del_count) + print("Kept back: %s " % depcache.keep_count) + + print("Trying DistUpgrade:") + depcache.upgrade(True) + print("To install: %s " % depcache.inst_count) + print("To remove: %s " % depcache.del_count) + print("Kept back: %s " % depcache.keep_count) + + +if __name__ == "__main__": + main() + sys.exit(0) diff --git a/tests/old/pkgrecords.py b/tests/old/pkgrecords.py new file mode 100644 index 0000000..b6be005 --- /dev/null +++ b/tests/old/pkgrecords.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python2.4 +# +# Test for the PkgSrcRecords code +# it segfaults for python-apt < 0.5.37 +# + +import sys + +import apt_pkg + + +def main(): + apt_pkg.init() + cache = apt_pkg.Cache() + depcache = apt_pkg.DepCache(cache) + depcache.init() + i = 0 + print("Running PkgRecords test on all packages:") + for pkg in cache.packages: + i += 1 + records = apt_pkg.PackageRecords(cache) + if len(pkg.version_list) == 0: + # print "no available version, cruft" + continue + version = depcache.get_candidate_ver(pkg) + if not version: + continue + file, index = version.file_list.pop(0) + if records.lookup((file, index)): + # print records.filename + records.filename + records.long_desc + print( + "\r%i/%i=%.3f%% " + % (i, cache.package_count, (float(i) / float(cache.package_count) * 100)) + ) + + +if __name__ == "__main__": + main() + sys.exit(0) diff --git a/tests/old/pkgsrcrecords.py b/tests/old/pkgsrcrecords.py new file mode 100644 index 0000000..ccf791f --- /dev/null +++ b/tests/old/pkgsrcrecords.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python2.4 +# +# Test for the PkgSrcRecords code +# it segfaults for python-apt < 0.5.37 +# + +import sys + +import apt_pkg + + +def main(): + apt_pkg.init() + cache = apt_pkg.Cache() + i = 0 + print("Running PkgSrcRecords test on all packages:") + for x in cache.packages: + i += 1 + src = apt_pkg.SourceRecords() + if src.lookup(x.name): + # print src.package + pass + print( + "\r%i/%i=%.3f%% " + % (i, cache.package_count, (float(i) / float(cache.package_count) * 100)) + ) + + +if __name__ == "__main__": + main() + sys.exit(0) diff --git a/tests/old/refcount.py b/tests/old/refcount.py new file mode 100755 index 0000000..0fad676 --- /dev/null +++ b/tests/old/refcount.py @@ -0,0 +1,54 @@ +#!/usr/bin/python-dbg + +import gc +import sys +from pprint import pprint + +import apt + +# get initial cache +print(sys.gettotalrefcount()) +progress = apt.progress.OpTextProgress() +c = apt.Cache(progress) +print("refcount after first cache instance: ", sys.gettotalrefcount()) + +# test open() +c.open(progress) +print("refcount after cache open: ", sys.gettotalrefcount()) +# pprint(sys.getobjects(10)) + +c.open(apt.progress.OpProgress()) +print("refcount after seconf cache open: ", sys.gettotalrefcount()) +# pprint(sys.getobjects(10)) + +# FIXME: find a way to get a efficient diff +# before = gc.get_objects() +# c.open(apt.progress.OpProgress()) +# after = gc.get_objects() + + +# test update() +print("refcount before cache.update(): ", sys.gettotalrefcount()) +c.update() +gc.collect() +print("refcount after cache.update(): ", sys.gettotalrefcount()) +c.update() +gc.collect() +print("refcount after second cache.update(): ", sys.gettotalrefcount()) +# pprint(sys.getobjects(20)) + + +# test install() +c.open(apt.progress.OpProgress()) +gc.collect() +print("refcount before cache['hello'].mark_install(): ", sys.gettotalrefcount()) +c["hello"].mark_install() +c.commit(apt.progress.FetchProgress(), apt.progress.InstallProgress()) +gc.collect() +print("refcount after: ", sys.gettotalrefcount()) +c.open(apt.progress.OpProgress()) +c["hello"].mark_delete() +c.commit(apt.progress.FetchProgress(), apt.progress.InstallProgress()) +gc.collect() +print("refcount after: ", sys.gettotalrefcount()) +pprint(sys.getobjects(10)) diff --git a/tests/old/test_enhances.py b/tests/old/test_enhances.py new file mode 100644 index 0000000..79aad9a --- /dev/null +++ b/tests/old/test_enhances.py @@ -0,0 +1,16 @@ +#!/usr/bin/python3 + +import apt + +cache = apt.Cache() + +for pkg in cache: + if pkg.installed and pkg.installed.enhances: + s = "%s enhances:" % pkg.name + for or_list in pkg.installed.enhances: + for enhances in or_list.or_dependencies: + s += " %s" % enhances.name + if enhances.name in cache and not cache[enhances.name].is_installed: + s += "(*missing*) " + s += "," + print(s[:-1]) diff --git a/tests/test_all.py b/tests/test_all.py new file mode 100644 index 0000000..c97ed5d --- /dev/null +++ b/tests/test_all.py @@ -0,0 +1,63 @@ +#!/usr/bin/python3 +# Copyright (C) 2009 Julian Andres Klode +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Run all available unit tests.""" +import os +import sys +import unittest +import unittest.runner + +# Python 3 only provides abiflags since 3.2 +if not hasattr(sys, "pydebug"): + if sys.abiflags.startswith("d"): + sys.pydebug = True + else: + sys.pydebug = False + + +def get_library_dir(): + # Find the path to the built apt_pkg and apt_inst extensions + if not os.path.exists("../build"): + return None + from sysconfig import get_platform, get_python_version + + # Set the path to the build directory. + plat_specifier = f".{get_platform()}-{get_python_version()}" + library_dir = "../build/lib{}{}".format( + plat_specifier, + (sys.pydebug and "-pydebug" or ""), + ) + return os.path.abspath(library_dir) + + +class MyTestRunner(unittest.runner.TextTestRunner): + def __init__(self, *args, **kwargs): + kwargs["stream"] = sys.stdout + super().__init__(*args, **kwargs) + + +if __name__ == "__main__": + if not os.access("/etc/apt/sources.list", os.R_OK): + sys.stdout.write("[tests] Skipping because sources.list is not readable\n") + sys.exit(0) + + sys.stdout.write("[tests] Running on %s\n" % sys.version.replace("\n", "")) + dirname = os.path.dirname(__file__) + if dirname: + os.chdir(dirname) + library_dir = get_library_dir() + if "pybuild" in os.getenv("PYTHONPATH", ""): + # pybuild already supplied us with a path to check for + sys.stdout.write("Using pybuild supplied build dir\n") + elif library_dir: + sys.stdout.write("Using library_dir: '%s'\n" % library_dir) + sys.path.insert(0, os.path.abspath(library_dir)) + + for path in os.listdir("."): + if path.endswith(".py") and os.path.isfile(path) and path.startswith("test_"): + exec("from %s import *" % path[:-3]) + + unittest.main(testRunner=MyTestRunner) diff --git a/tests/test_apt_cache.py b/tests/test_apt_cache.py new file mode 100644 index 0000000..cc52400 --- /dev/null +++ b/tests/test_apt_cache.py @@ -0,0 +1,400 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2010 Julian Andres Klode +# 2010 Michael Vogt +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of check_dep, etc in apt_pkg.""" + +import glob +import logging +import os +import shutil +import sys +import tempfile +import unittest + +from test_all import get_library_dir + +libdir = get_library_dir() +if libdir: + sys.path.insert(0, libdir) + +import apt_pkg +import testcommon + +import apt + + +def if_sources_list_is_readable(f): + def wrapper(*args, **kwargs): + if os.access("/etc/apt/sources.list", os.R_OK): + f(*args, **kwargs) + else: + logging.warning("skipping '%s' because sources.list is not readable" % f) + + return wrapper + + +def get_open_file_descriptors(): + try: + fds = os.listdir("/proc/self/fd") + except OSError: + logging.warning("failed to list /proc/self/fd") + return set() + return set(map(int, fds)) + + +class TestAptCache(testcommon.TestCase): + """test the apt cache""" + + def setUp(self): + testcommon.TestCase.setUp(self) + apt_pkg.config.clear("APT::Update::Post-Invoke") + apt_pkg.config.clear("APT::Update::Post-Invoke-Success") + + @if_sources_list_is_readable + def test_apt_cache(self): + """cache: iterate all packages and all dependencies""" + cache = apt.Cache() + # number is not meaningful and just need to be "big enough", + # the important bit is the test against __len__ + self.assertTrue(len(cache) > 100) + # go over the cache and all dependencies, just to see if + # that is possible and does not crash + for pkg in cache: + if pkg.candidate: + for or_deps in pkg.candidate.dependencies: + for dep in or_deps: + self.assertTrue(dep.name) + self.assertTrue(isinstance(dep.relation, str)) + self.assertTrue(dep.pre_depend in (True, False)) + + # accessing record should take a reasonable time; in + # particular, when using compressed indexes, it should not use + # tons of seek operations + r = pkg.candidate.record + self.assertEqual(r["Package"], pkg.shortname) + self.assertTrue("Version" in r) + self.assertTrue(len(r["Description"]) > 0) + self.assertTrue(str(r).startswith("Package: %s\n" % pkg.shortname)) + + @if_sources_list_is_readable + def test_cache_close_leak_fd(self): + fds_before_open = get_open_file_descriptors() + cache = apt.Cache() + opened_fd = get_open_file_descriptors().difference(fds_before_open) + cache.close() + fds_after_close = get_open_file_descriptors() + unclosed_fd = opened_fd.intersection(fds_after_close) + self.assertEqual(fds_before_open, fds_after_close) + self.assertEqual(unclosed_fd, set()) + + def test_cache_open_twice_leaks_fds(self): + cache = apt.Cache() + fds_before_open = get_open_file_descriptors() + cache.open() + fds_after_open_twice = get_open_file_descriptors() + self.assertEqual(fds_before_open, fds_after_open_twice) + + @if_sources_list_is_readable + def test_cache_close_download_fails(self): + cache = apt.Cache() + self.assertEqual(cache.required_download, 0) + cache.close() + with self.assertRaises(apt.cache.CacheClosedException): + cache.required_download + + def test_get_provided_packages(self): + apt.apt_pkg.config.set("Apt::architecture", "i386") + cache = apt.Cache(rootdir="./data/test-provides/") + cache.open() + if len(cache) == 0: + logging.warning("skipping test_get_provided_packages, cache empty?!?") + return + # a true virtual pkg + li = cache.get_providing_packages("mail-transport-agent") + self.assertTrue(len(li) > 0) + self.assertTrue("postfix" in [p.name for p in li]) + self.assertTrue("mail-transport-agent" in cache["postfix"].candidate.provides) + + def test_low_level_pkg_provides(self): + apt.apt_pkg.config.set("Apt::architecture", "i386") + # create highlevel cache and get the lowlevel one from it + highlevel_cache = apt.Cache(rootdir="./data/test-provides") + if len(highlevel_cache) == 0: + logging.warning("skipping test_log_level_pkg_provides, cache empty?!?") + return + # low level cache provides list of the pkg + cache = highlevel_cache._cache + li = cache["mail-transport-agent"].provides_list + # arbitrary number, just needs to be higher enough + self.assertEqual(len(li), 2) + for providesname, providesver, version in li: + self.assertEqual(providesname, "mail-transport-agent") + if version.parent_pkg.name == "postfix": + break + else: + self.assertNotReached() + + @if_sources_list_is_readable + def test_dpkg_journal_dirty(self): + # create tmp env + tmpdir = tempfile.mkdtemp() + dpkg_dir = os.path.join(tmpdir, "var", "lib", "dpkg") + os.makedirs(os.path.join(dpkg_dir, "updates")) + open(os.path.join(dpkg_dir, "status"), "w").close() + apt_pkg.config.set("Dir::State::status", os.path.join(dpkg_dir, "status")) + cache = apt.Cache() + # test empty + self.assertFalse(cache.dpkg_journal_dirty) + # that is ok, only [0-9] are dpkg jounral entries + open(os.path.join(dpkg_dir, "updates", "xxx"), "w").close() + self.assertFalse(cache.dpkg_journal_dirty) + # that is a dirty journal + open(os.path.join(dpkg_dir, "updates", "000"), "w").close() + self.assertTrue(cache.dpkg_journal_dirty) + + @if_sources_list_is_readable + def test_apt_update(self): + rootdir = "./data/tmp" + if os.path.exists(rootdir): + shutil.rmtree(rootdir) + try: + os.makedirs(os.path.join(rootdir, "var/lib/apt/lists/partial")) + except OSError: + pass + state_dir = os.path.join(rootdir, "var/lib/apt") + lists_dir = os.path.join(rootdir, "var/lib/apt/lists") + old_state = apt_pkg.config.find("dir::state") + apt_pkg.config.set("dir::state", state_dir) + # set a local sources.list that does not need the network + base_sources = os.path.abspath(os.path.join(rootdir, "sources.list")) + old_source_list = apt_pkg.config.find("dir::etc::sourcelist") + old_source_parts = apt_pkg.config.find("dir::etc::sourceparts") + apt_pkg.config.set("dir::etc::sourcelist", base_sources) + # TODO: /dev/null is not a dir, perhaps find something better + apt_pkg.config.set("dir::etc::sourceparts", "/dev/null") + # main sources.list + sources_list = base_sources + with open(sources_list, "w") as f: + repo = os.path.abspath("./data/test-repo2") + f.write("deb [allow-insecure=yes] copy:%s /\n" % repo) + + # test single sources.list fetching + sources_list = os.path.join(rootdir, "test.list") + with open(sources_list, "w") as f: + repo_dir = os.path.abspath("./data/test-repo") + f.write("deb [allow-insecure=yes] copy:%s /\n" % repo_dir) + + self.assertTrue(os.path.exists(sources_list)) + # write marker to ensure listcleaner is not run + open("./data/tmp/var/lib/apt/lists/marker", "w").close() + + # update a single sources.list + cache = apt.Cache() + cache.update(sources_list=sources_list) + # verify we just got the excpected package file + needle_packages = glob.glob(lists_dir + "/*tests_data_test-repo_Packages*") + self.assertEqual(len(needle_packages), 1) + # verify that we *only* got the Packages file from a single source + all_packages = glob.glob(lists_dir + "/*_Packages*") + self.assertEqual(needle_packages, all_packages) + # verify that the listcleaner was not run and the marker file is + # still there + self.assertTrue("marker" in os.listdir(lists_dir)) + # now run update again (without the "normal" sources.list that + # contains test-repo2 and verify that we got the normal sources.list + cache.update() + needle_packages = glob.glob(lists_dir + "/*tests_data_test-repo2_Packages*") + self.assertEqual(len(needle_packages), 1) + all_packages = glob.glob(lists_dir + "/*_Packages*") + self.assertEqual(needle_packages, all_packages) + + # and another update with a single source only + cache = apt.Cache() + cache.update(sources_list=sources_list) + all_packages = glob.glob(lists_dir + "/*_Packages*") + self.assertEqual(len(all_packages), 2) + apt_pkg.config.set("dir::state", old_state) + apt_pkg.config.set("dir::etc::sourcelist", old_source_list) + apt_pkg.config.set("dir::etc::sourceparts", old_source_parts) + + def test_package_cmp(self): + cache = apt.Cache(rootdir="/") + li = [] + li.append(cache["intltool"]) + li.append(cache["python3"]) + li.append(cache["apt"]) + li.sort() + self.assertEqual([p.name for p in li], ["apt", "intltool", "python3"]) + + def test_get_architectures(self): + main_arch = apt.apt_pkg.config.get("APT::Architecture") + arches = apt_pkg.get_architectures() + self.assertTrue(main_arch in arches) + + def test_phasing_applied(self): + """checks the return type of phasing_applied.""" + cache = apt.Cache() + pkg = cache["apt"] + self.assertIsInstance(pkg.phasing_applied, bool) + + def test_is_security_update(self): + """checks the return type of is_security_update.""" + cache = apt.Cache() + pkg = cache["apt"] + self.assertIsInstance(pkg.installed.is_security_update, bool) + + def test_apt_cache_reopen_is_safe(self): + """cache: check that we cannot use old package objects after reopen""" + cache = apt.Cache() + old_depcache = cache._depcache + old_package = cache["apt"] + old_pkg = old_package._pkg + old_version = old_package.candidate + old_ver = old_version._cand + + cache.open() + new_depcache = cache._depcache + new_package = cache["apt"] + new_pkg = new_package._pkg + new_version = new_package.candidate + new_ver = new_version._cand + + # get candidate + self.assertRaises(ValueError, old_depcache.get_candidate_ver, new_pkg) + self.assertRaises(ValueError, new_depcache.get_candidate_ver, old_pkg) + self.assertEqual(new_ver, new_depcache.get_candidate_ver(new_pkg)) + self.assertEqual(old_package.candidate._cand, old_ver) # Remap success + self.assertEqual( + old_package.candidate._cand, new_depcache.get_candidate_ver(new_pkg) + ) + + # set candidate + new_package.candidate = old_version + old_depcache.set_candidate_ver(old_pkg, old_ver) + self.assertRaises(ValueError, old_depcache.set_candidate_ver, old_pkg, new_ver) + self.assertRaises(ValueError, new_depcache.set_candidate_ver, old_pkg, old_ver) + self.assertRaises(ValueError, new_depcache.set_candidate_ver, old_pkg, new_ver) + self.assertRaises(ValueError, new_depcache.set_candidate_ver, new_pkg, old_ver) + new_depcache.set_candidate_ver(new_pkg, new_ver) + + @staticmethod + def write_status_file(packages): + with open(apt_pkg.config["Dir::State::Status"], "w") as fobj: + for package in packages: + print("Package:", package, file=fobj) + print("Status: install ok installed", file=fobj) + print("Priority: optional", file=fobj) + print("Section: admin", file=fobj) + print("Installed-Size: 1", file=fobj) + print("Maintainer: X ", file=fobj) + print("Architecture: all", file=fobj) + print("Version: 1", file=fobj) + print("Description: blah", file=fobj) + print("", file=fobj) + + def test_apt_cache_reopen_is_safe_out_of_bounds(self): + """Check that out of bounds access is remapped correctly.""" + with tempfile.NamedTemporaryFile() as status: + apt_pkg.config["Dir::Etc::SourceList"] = "/dev/null" + apt_pkg.config["Dir::Etc::SourceParts"] = "/dev/null" + apt_pkg.config["Dir::State::Status"] = status.name + apt_pkg.init_system() + + self.write_status_file("abcdefghijklmnopqrstuvwxyz") + c = apt.Cache() + p = c["z"] + p_id = p.id + self.write_status_file("az") + apt_pkg.init_system() + c.open() + self.assertNotEqual(p.id, p_id) + self.assertLess(p.id, 2) + p.mark_delete() + self.assertEqual([p], c.get_changes()) + + def test_apt_cache_reopen_is_safe_out_of_bounds_no_match(self): + """Check that installing gone package raises correct exception""" + with tempfile.NamedTemporaryFile() as status: + apt_pkg.config["Dir::Etc::SourceList"] = "/dev/null" + apt_pkg.config["Dir::Etc::SourceParts"] = "/dev/null" + apt_pkg.config["Dir::State::Status"] = status.name + apt_pkg.init_system() + + self.write_status_file("abcdefghijklmnopqrstuvwxyz") + c = apt.Cache() + p = c["z"] + p_id = p.id + self.write_status_file("a") + apt_pkg.init_system() + c.open() + self.assertEqual(p.id, p_id) # Could not be remapped + self.assertRaises(apt_pkg.CacheMismatchError, p.mark_delete) + + def test_apt_cache_reopen_is_safe_swap(self): + """Check that swapping a and b does not mark the wrong package.""" + with tempfile.NamedTemporaryFile() as status: + apt_pkg.config["Dir::Etc::SourceList"] = "/dev/null" + apt_pkg.config["Dir::Etc::SourceParts"] = "/dev/null" + apt_pkg.config["Dir::State::Status"] = status.name + apt_pkg.init_system() + + self.write_status_file("abcdefghijklmnopqrstuvwxyz") + c = apt.Cache() + p = c["a"] + a_id = p.id + p_hash = hash(p) + set_of_p = {p} + self.write_status_file("baz") + apt_pkg.init_system() + c.open() + # b now has the same id as a in the old cache + self.assertEqual(c["b"].id, a_id) + self.assertNotEqual(p.id, a_id) + # Marking a should still mark a, not b. + p.mark_delete() + self.assertEqual([p], c.get_changes()) + + # Ensure that p can still be found in a set of it, as a test + # for bug https://bugs.launchpad.net/bugs/1780099 + self.assertEqual(hash(p), p_hash) + self.assertIn(p, set_of_p) + + def test_apt_cache_iteration_safe(self): + """Check that iterating does not produce different results. + + This failed in 1.7.0~alpha2, because one part of the code + looked up packages in the weak dict using the pretty name, + and the other using the full name.""" + + with tempfile.NamedTemporaryFile() as status: + apt_pkg.config["Dir::Etc::SourceList"] = "/dev/null" + apt_pkg.config["Dir::Etc::SourceParts"] = "/dev/null" + apt_pkg.config["Dir::State::Status"] = status.name + apt_pkg.init_system() + + self.write_status_file("abcdefghijklmnopqrstuvwxyz") + + c = apt.Cache() + c["a"].mark_delete() + self.assertEqual([c["a"]], [p for p in c if p.marked_delete]) + + def test_problemresolver_keep_phased_updates(self): + """Check that the c++ function can be called.""" + with tempfile.NamedTemporaryFile() as status: + apt_pkg.config["Dir::Etc::SourceList"] = "/dev/null" + apt_pkg.config["Dir::Etc::SourceParts"] = "/dev/null" + apt_pkg.config["Dir::State::Status"] = status.name + apt_pkg.init_system() + + cache = apt.Cache() + problemresolver = apt.ProblemResolver(cache) + self.assertIsNone(problemresolver.keep_phased_updates()) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_aptsources.py b/tests/test_aptsources.py new file mode 100644 index 0000000..1e04552 --- /dev/null +++ b/tests/test_aptsources.py @@ -0,0 +1,1573 @@ +#!/usr/bin/python3 + +import copy +import os +import tempfile +import unittest + +import apt_pkg +import testcommon + +import aptsources.distro +import aptsources.sourceslist + + +class TestAptSources(testcommon.TestCase): + def setUp(self): + testcommon.TestCase.setUp(self) + if apt_pkg.config["APT::Architecture"] not in ("i386", "amd64"): + apt_pkg.config.set("APT::Architecture", "i386") + apt_pkg.config.set("Dir::Etc", os.getcwd()) + apt_pkg.config.set("Dir::Etc::sourceparts", tempfile.mkdtemp()) + if os.path.exists("./build/data/templates"): + self.templates = os.path.abspath("./build/data/templates") + elif os.path.exists("../build/data/templates"): + self.templates = os.path.abspath("../build/data/templates") + else: + self.templates = "/usr/share/python-apt/templates/" + + def tearDown(self): + aptsources.distro._OSRelease.OS_RELEASE_FILE = ( + aptsources.distro._OSRelease.DEFAULT_OS_RELEASE_FILE + ) + if "LSB_ETC_LSB_RELEASE" in os.environ: + del os.environ["LSB_ETC_LSB_RELEASE"] + + def testIsMirror(self): + """aptsources: Test mirror detection.""" + yes = aptsources.sourceslist.is_mirror( + "http://archive.ubuntu.com", "http://de.archive.ubuntu.com" + ) + no = aptsources.sourceslist.is_mirror( + "http://archive.ubuntu.com", "http://ftp.debian.org" + ) + self.assertTrue(yes) + self.assertFalse(no) + + def testSourcesListReading(self): + """aptsources: Test sources.list parsing.""" + apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list") + sources = aptsources.sourceslist.SourcesList(True, self.templates) + self.assertEqual(len(sources.list), 10) + # test load + sources.list = [] + sources.load("data/aptsources/sources.list") + self.assertEqual(len(sources.list), 10) + + def testSourcesListReading_deb822(self): + """aptsources: Test sources.list parsing.""" + apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d") + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + self.assertEqual(len(sources.list), 5) + # test load + sources.list = [] + sources.load("data/aptsources/sources.list.d/main.sources") + self.assertEqual(len(sources.list), 5) + + for entry in sources.list: + self.assertFalse(entry.invalid) + self.assertFalse(entry.disabled) + self.assertEqual(entry.types, ["deb"]) + self.assertEqual(entry.type, "deb") + self.assertEqual(entry.uris, ["http://de.archive.ubuntu.com/ubuntu/"]) + self.assertEqual(entry.uri, "http://de.archive.ubuntu.com/ubuntu/") + + self.assertEqual(sources.list[0].comps, ["main"]) + self.assertEqual(sources.list[1].comps, ["restricted"]) + self.assertEqual(sources.list[2].comps, ["universe"]) + self.assertEqual(sources.list[3].comps, ["main"]) + self.assertEqual(sources.list[4].comps, ["main"]) + + for entry in sources.list[:-1]: + self.assertIsNone(entry.trusted) + + self.assertTrue(sources.list[-1].trusted) + + for entry in sources.list[:-2]: + self.assertEqual(entry.architectures, []) + self.assertEqual(entry.suites, ["edgy"]) + self.assertEqual(entry.dist, "edgy") + + for entry in sources.list[-2:]: + self.assertEqual(entry.suites, ["natty"]) + self.assertEqual(entry.dist, "natty") + self.assertEqual(entry.architectures, ["amd64", "i386"]) + + def testSourcesListWriting_deb822(self): + """aptsources: Test sources.list parsing.""" + apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d") + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + with tempfile.TemporaryDirectory() as tmpdir: + for entry in sources.list: + entry.file = os.path.join(tmpdir, os.path.basename(entry.file)) + + sources.save() + + maxDiff = self.maxDiff + self.maxDiff = None + for file in os.listdir("data/aptsources/sources.list.d"): + with open(os.path.join("data/aptsources/sources.list.d", file)) as a: + with open(os.path.join(tmpdir, file)) as b: + self.assertEqual(a.read(), b.read(), f"file {file}") + self.maxDiff = maxDiff + + def testSourcesListAdding(self): + """aptsources: Test additions to sources.list""" + apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list") + sources = aptsources.sourceslist.SourcesList(True, self.templates) + # test to add something that is already there (main) + before = copy.deepcopy(sources) + sources.add("deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["main"]) + self.assertTrue(sources.list == before.list) + # test to add something that is already there (restricted) + before = copy.deepcopy(sources) + sources.add( + "deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["restricted"] + ) + self.assertTrue(sources.list == before.list) + + before = copy.deepcopy(sources) + sources.add( + "deb", + "http://de.archive.ubuntu.com/ubuntu/", + "natty", + ["main"], + architectures=["amd64", "i386"], + ) + self.assertTrue(sources.list == before.list) + + # test to add something new: multiverse + sources.add( + "deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["multiverse"] + ) + found = False + for entry in sources: + if ( + entry.type == "deb" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "edgy" + and "multiverse" in entry.comps + ): + found = True + break + self.assertTrue(found) + + # add a new natty entry without architecture specification + sources.add( + "deb", "http://de.archive.ubuntu.com/ubuntu/", "natty", ["multiverse"] + ) + found = False + for entry in sources: + if ( + entry.type == "deb" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "natty" + and entry.architectures == [] + and "multiverse" in entry.comps + ): + found = True + break + self.assertTrue(found) + + # Add universe to existing multi-arch line + sources.add( + "deb", + "http://de.archive.ubuntu.com/ubuntu/", + "natty", + ["universe"], + architectures=["i386", "amd64"], + ) + found = False + for entry in sources: + if ( + entry.type == "deb" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "natty" + and set(entry.architectures) == {"amd64", "i386"} + and set(entry.comps) == {"main", "universe"} + ): + found = True + break + self.assertTrue(found) + # test to add something new: multiverse *and* + # something that is already there + before = copy.deepcopy(sources) + sources.add( + "deb", + "http://de.archive.ubuntu.com/ubuntu/", + "edgy", + ["universe", "something"], + ) + found_universe = 0 + found_something = 0 + for entry in sources: + if ( + entry.type == "deb" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "edgy" + ): + for c in entry.comps: + if c == "universe": + found_universe += 1 + if c == "something": + found_something += 1 + # print "\n".join([s.str() for s in sources]) + self.assertEqual(found_something, 1) + self.assertEqual(found_universe, 1) + + def testSourcesListAdding_deb822(self): + """aptsources: Test additions to sources.list""" + apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d") + + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + # test to add something that is already there (main) + before = copy.deepcopy(sources) + sources.add("deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["main"]) + self.assertEqual(sources.list, before.list) + # test to add something that is already there (restricted) + before = copy.deepcopy(sources) + sources.add( + "deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["restricted"] + ) + self.assertTrue(sources.list == before.list) + + before = copy.deepcopy(sources) + sources.add( + "deb", + "http://de.archive.ubuntu.com/ubuntu/", + "natty", + ["main"], + architectures=["amd64", "i386"], + ) + self.assertEqual( + [e.str() for e in sources.list], [e.str() for e in before.list] + ) + + # test to add something new: multiverse + sources.add( + "deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["multiverse"] + ) + found = False + for entry in sources: + if ( + entry.type == "deb" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "edgy" + and "multiverse" in entry.comps + ): + found = True + break + self.assertTrue(found) + + # add a new natty entry without architecture specification + sources.add( + "deb", "http://de.archive.ubuntu.com/ubuntu/", "natty", ["multiverse"] + ) + found = False + for entry in sources: + if ( + entry.type == "deb" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "natty" + and entry.architectures == [] + and "multiverse" in entry.comps + ): + found = True + break + self.assertTrue(found) + + # Add universe to existing multi-arch line + sources.add( + "deb", + "http://de.archive.ubuntu.com/ubuntu/", + "natty", + ["universe"], + architectures=["i386", "amd64"], + ) + found = False + for entry in sources: + if ( + entry.type == "deb" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "natty" + and set(entry.architectures) == {"amd64", "i386"} + and set(entry.comps) == {"main", "universe"} + ): + found = True + break + self.assertTrue(found) + # test to add something new: multiverse *and* + # something that is already there + before = copy.deepcopy(sources) + sources.add( + "deb", + "http://de.archive.ubuntu.com/ubuntu/", + "edgy", + ["universe", "something"], + ) + found_universe = 0 + found_something = 0 + for entry in sources: + if ( + entry.type == "deb" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "edgy" + ): + for c in entry.comps: + if c == "universe": + found_universe += 1 + if c == "something": + found_something += 1 + # print "\n".join([s.str() for s in sources]) + self.assertEqual(found_something, 1) + self.assertEqual(found_universe, 1) + + def testAddingWithComment_deb822(self): + apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d") + self._commonTestAddingWithComment() + + def testAddingWithComment_short(self): + apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list") + self._commonTestAddingWithComment() + + def _commonTestAddingWithComment(self): + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + + # test to add something that is already there (main); loses comment + before = copy.deepcopy(sources) + sources.add( + "deb", + "http://de.archive.ubuntu.com/ubuntu/", + "edgy", + ["main"], + comment="this will be lost", + ) + self.assertTrue(sources.list == before.list) + for entry in sources: + self.assertNotEqual(entry.comment, "this will be lost") + + # test to add component to existing entry: multiverse; loses comment + sources.add( + "deb", + "http://de.archive.ubuntu.com/ubuntu/", + "edgy", + ["multiverse"], + comment="this will be lost", + ) + for entry in sources: + self.assertNotEqual(entry.comment, "this will be lost") + + before = copy.deepcopy(sources) + # test to add entirely new entry; retains comment + sources.add( + "deb-src", + "http://de.archive.ubuntu.com/ubuntu/", + "edgy", + ["main"], + comment="this will appear", + file=sources.list[0].file, # make sure we test the deb822 code path + ) + self.assertNotEqual(sources.list, before.list) + self.assertEqual(len(sources.list), len(before.list) + 1) + found = False + for entry in sources: + if ( + entry.type == "deb-src" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "edgy" + and entry.comment == "this will appear" + and "main" in entry.comps + ): + found = True + break + self.assertTrue(found) + + def testInsertion_deb822(self): + apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d") + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + + # test to insert something that is already there (universe); does not + # move existing entry (remains at index 2) + before = copy.deepcopy(sources) + sources.add( + "deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["universe"], pos=0 + ) + self.assertTrue(sources.list == before.list) + entry = list(sources)[2] + self.assertEqual(entry.type, "deb") + self.assertEqual(entry.uri, "http://de.archive.ubuntu.com/ubuntu/") + self.assertEqual(entry.dist, "edgy") + self.assertIn("universe", entry.comps) + + # test add component to existing entry: multiverse; does not move + # entry to which it is appended (remains at index 0) + sources.add( + "deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["multiverse"], pos=2 + ) + entry = list(sources)[0] + self.assertTrue( + entry.type == "deb" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "edgy" + and {"main", "multiverse"} <= set(entry.comps) + ) + + # test to add entirely new entry; inserted at 0 + sources.add( + "deb-src", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["main"], pos=0 + ) + entry = list(sources)[0] + self.assertTrue( + entry.type == "deb-src" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "edgy" + and "main" in entry.comps + ) + + def testInsertion(self): + apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list") + sources = aptsources.sourceslist.SourcesList(True, self.templates) + + # test to insert something that is already there (universe); does not + # move existing entry (remains at index 2) + before = copy.deepcopy(sources) + sources.add( + "deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["universe"], pos=0 + ) + self.assertTrue(sources.list == before.list) + entry = list(sources)[5] + self.assertTrue( + entry.type == "deb" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "edgy" + and "universe" in entry.comps + ) + + # test add component to existing entry: multiverse; does not move + # entry to which it is appended (remains at index 0) + sources.add( + "deb", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["multiverse"], pos=2 + ) + entry = list(sources)[1] + self.assertTrue( + entry.type == "deb" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "edgy" + and {"main", "multiverse"} <= set(entry.comps) + ) + + # test to add entirely new entry; inserted at 0 + sources.add( + "deb-src", "http://de.archive.ubuntu.com/ubuntu/", "edgy", ["main"], pos=0 + ) + entry = list(sources)[0] + self.assertTrue( + entry.type == "deb-src" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and entry.dist == "edgy" + and "main" in entry.comps + ) + + def testDuplication_short(self): + apt_pkg.config.set( + "Dir::Etc::sourcelist", "data/aptsources/sources.list.testDuplication" + ) + return self.commonTestDuplication() + + def testDuplication_deb822(self): + apt_pkg.config.set( + "Dir::Etc::sourceparts", "data/aptsources/sources.list.d.testDuplication" + ) + return self.commonTestDuplication() + + def commonTestDuplication(self): + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + test_url = "http://ppa.launchpad.net/me/myproject/ubuntu" + # test to add something that is already there (enabled) + before = copy.deepcopy(sources) + sources.add("deb", test_url, "xenial", ["main"]) + self.assertEqual(sources.list, before.list) + # test to add something that is already there (disabled) + sources.add("# deb-src", test_url, "xenial", ["main"]) + self.assertEqual(sources.list, before.list) + # test to enable something that is already there + sources.add("deb-src", test_url, "xenial", ["main"]) + found = False + self.assertEqual(len(sources.list), 2) + for entry in sources: + if ( + entry.type == "deb-src" + and not entry.disabled + and entry.uri == test_url + and entry.dist == "xenial" + and entry.architectures == [] + and entry.comps == ["main"] + ): + found = True + break + self.assertTrue(found) + + def testMatcher_short(self): + """aptsources: Test matcher""" + apt_pkg.config.set( + "Dir::Etc::sourcelist", "data/aptsources/" "sources.list.testDistribution" + ) + return self.commonTestMatcher() + + def testMatcher_deb822(self): + """aptsources: Test matcher""" + apt_pkg.config.set( + "Dir::Etc::sourceparts", + "data/aptsources/" "sources.list.d.testDistribution", + ) + return self.commonTestMatcher() + + def commonTestMatcher(self): + """aptsources: Test matcher""" + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + distro = aptsources.distro.get_distro( + id="Ubuntu", + codename="bionic", + description="Ubuntu 18.04 LTS", + release="18.04", + ) + distro.get_sources(sources) + # test if all suits of the current distro were detected correctly + self.assertNotEqual(sources.list, []) + for s in sources: + if not s.template: + self.fail("source entry '%s' has no matcher" % s) + + # Hack in a check for splitting of fields here. + if sources.list[-1].file.endswith(".sources"): + self.assertEqual( + sources.list[-1].uris, ["cdrom:[Ubuntu 8.04 _Hardy Heron_]"] + ) + self.assertEqual(sources.list[-1].uri, "cdrom:[Ubuntu 8.04 _Hardy Heron_]") + + def testMultiArch(self): + """aptsources: Test multi-arch parsing""" + + apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list") + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + assert not sources.list[8].invalid + assert sources.list[8].type == "deb" + assert sources.list[8].architectures == ["amd64", "i386"] + assert sources.list[8].uri == "http://de.archive.ubuntu.com/ubuntu/" + assert sources.list[8].dist == "natty" + assert sources.list[8].comps == ["main"] + assert sources.list[8].line.strip() == str(sources.list[8]) + assert sources.list[8].trusted is None + + def testMultiArch_deb822(self): + """aptsources: Test multi-arch parsing""" + + apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d") + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + assert not sources.list[3].invalid + assert sources.list[3].type == "deb" + assert sources.list[3].architectures == ["amd64", "i386"] + assert sources.list[3].uri == "http://de.archive.ubuntu.com/ubuntu/" + assert sources.list[3].dist == "natty" + assert sources.list[3].comps == ["main"] + self.assertEqual(sources.list[3].line.strip(), str(sources.list[3])) + self.assertIsNone(sources.list[3].trusted) + + def testMultipleOptions(self): + """aptsources: Test multi-arch parsing""" + + apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list") + sources = aptsources.sourceslist.SourcesList(True, self.templates) + assert sources.list[9].invalid is False + assert sources.list[9].type == "deb" + assert sources.list[9].architectures == ["amd64", "i386"] + self.assertEqual(sources.list[9].uri, "http://de.archive.ubuntu.com/ubuntu/") + assert sources.list[9].dist == "natty" + assert sources.list[9].comps == ["main"] + assert sources.list[9].trusted + assert sources.list[9].line.strip() == str(sources.list[9]) + + def testMultipleOptions_deb822(self): + """aptsources: Test multi-arch parsing""" + + apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d") + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + assert sources.list[4].invalid is False + assert sources.list[4].type == "deb" + assert sources.list[4].architectures == ["amd64", "i386"] + self.assertEqual(sources.list[4].uri, "http://de.archive.ubuntu.com/ubuntu/") + assert sources.list[4].dist == "natty" + assert sources.list[4].comps == ["main"] + assert sources.list[4].trusted + assert sources.list[4].line.strip() == str(sources.list[4]) + + def test_enable_component(self): + target = "./data/aptsources/sources.list.enable_comps" + line = "deb http://archive.ubuntu.com/ubuntu lucid main\n" + with open(target, "w") as target_file: + target_file.write(line) + apt_pkg.config.set("Dir::Etc::sourcelist", target) + sources = aptsources.sourceslist.SourcesList(True, self.templates) + distro = aptsources.distro.get_distro( + id="Ubuntu", codename="lucid", release="10.04", description="Ubuntu 10.04" + ) + # and get the sources + distro.get_sources(sources) + # test enable_component + comp = "multiverse" + distro.enable_component(comp) + comps = set() + for entry in sources: + comps = comps.union(set(entry.comps)) + self.assertTrue("multiverse" in comps) + self.assertTrue("universe" in comps) + + def test_enable_component_deb822(self): + target = ( + apt_pkg.config.find_dir("dir::etc::sourceparts") + "enable_comps.sources" + ) + line = "Types: deb\nURIs: http://archive.ubuntu.com/ubuntu\nSuites: lucid\nComponents: main\n" + with open(target, "w") as target_file: + target_file.write(line) + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + distro = aptsources.distro.get_distro( + id="Ubuntu", codename="lucid", release="10.04", description="Ubuntu 10.04" + ) + # and get the sources + distro.get_sources(sources) + # test enable_component + comp = "multiverse" + distro.enable_component(comp) + comps = set() + for entry in sources: + comps = comps.union(set(entry.comps)) + self.assertTrue("multiverse" in comps) + self.assertTrue("universe" in comps) + + def test_enable_component_deb822_multi(self): + apt_pkg.config.set("Dir::Etc::sourcelist", "/dev/null") + + target = ( + apt_pkg.config.find_dir("dir::etc::sourceparts") + "enable_comps.sources" + ) + line = "Types: deb\nURIs: http://archive.ubuntu.com/ubuntu\nSuites: lucid lucid-updates\nComponents: main\n" + with open(target, "w") as target_file: + target_file.write(line) + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + distro = aptsources.distro.get_distro( + id="Ubuntu", codename="lucid", release="10.04", description="Ubuntu 10.04" + ) + # and get the sources + distro.get_sources(sources) + self.assertEqual(len(distro.main_sources), 1) + self.assertEqual(len(sources.list), 1) + # test enable_component + comp = "multiverse" + distro.enable_component(comp) + self.assertEqual(len(sources.list), 2) # split into two + + self.assertEqual( + "Types: deb\n" + "URIs: http://archive.ubuntu.com/ubuntu\n" + "Suites: lucid\n" + "Components: main multiverse universe", + str(sources.list[0]), + ) + self.assertEqual( + "Types: deb\n" + "URIs: http://archive.ubuntu.com/ubuntu\n" + "Suites: lucid-updates\n" + "Components: main multiverse universe", + str(sources.list[1]), + ) + + comps = set() + for entry in sources: + comps = comps.union(set(entry.comps)) + self.assertTrue("multiverse" in comps) + self.assertTrue("universe" in comps) + + sources.save() + self.assertEqual( + "Types: deb\n" + "URIs: http://archive.ubuntu.com/ubuntu\n" + "Suites: lucid lucid-updates\n" + "Components: main multiverse universe", + str(sources.list[0]), + ) + + def test_enable_component_deb822_multi_mixed_origin(self): + apt_pkg.config.set("Dir::Etc::sourcelist", "/dev/null") + + target = ( + apt_pkg.config.find_dir("dir::etc::sourceparts") + "enable_comps.sources" + ) + line = "Types: deb\nURIs: http://archive.ubuntu.com/ubuntu http://example.com/\nSuites: lucid\nComponents: main\n" + with open(target, "w") as target_file: + target_file.write(line) + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + distro = aptsources.distro.get_distro( + id="Ubuntu", codename="lucid", release="10.04", description="Ubuntu 10.04" + ) + # and get the sources + distro.get_sources(sources) + self.assertEqual(len(distro.main_sources), 2) + self.assertEqual(len(sources.list), 1) + # test enable_component + comp = "multiverse" + distro.enable_component(comp) + self.assertEqual(len(sources.list), 2) # split into two + + self.assertEqual( + "Types: deb\n" + "URIs: http://archive.ubuntu.com/ubuntu\n" + "Suites: lucid\n" + "Components: main multiverse universe", + str(sources.list[0]), + ) + self.assertEqual( + "Types: deb\n" + "URIs: http://example.com/\n" + "Suites: lucid\n" + "Components: main", + str(sources.list[1]), + ) + + sources.save() + self.assertEqual( + "Types: deb\n" + "URIs: http://archive.ubuntu.com/ubuntu\n" + "Suites: lucid\n" + "Components: main multiverse universe", + str(sources.list[0]), + ) + self.assertEqual( + "Types: deb\n" + "URIs: http://example.com/\n" + "Suites: lucid\n" + "Components: main", + str(sources.list[1]), + ) + + def test_enable_component_deb822_multi_mixed_ultimate(self): + apt_pkg.config.set("Dir::Etc::sourcelist", "/dev/null") + + target = ( + apt_pkg.config.find_dir("dir::etc::sourceparts") + "enable_comps.sources" + ) + line = "Types: deb deb-src\nURIs: http://archive.ubuntu.com/ubuntu http://example.com/\nSuites: lucid lucid-updates notalucid\nComponents: main\n" + with open(target, "w") as target_file: + target_file.write(line) + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + distro = aptsources.distro.get_distro( + id="Ubuntu", codename="lucid", release="10.04", description="Ubuntu 10.04" + ) + # and get the sources + distro.get_sources(sources) + self.assertEqual(len(distro.main_sources), 1) + self.assertEqual(len(sources.list), 1) + self.assertEqual(len(sources.exploded_list()), 12) + # test enable_component + comp = "multiverse" + distro.enable_component(comp) + self.assertEqual(len(sources.list), 12) # split into two + + expected = [] + for typ in "deb", "deb-src": + for uri in "http://archive.ubuntu.com/ubuntu", "http://example.com/": + for suite in "lucid", "lucid-updates", "notalucid": + comps = "main multiverse universe" + # unofficial source ends up without enablement + if uri == "http://example.com/" or suite == "notalucid": + comps = "main" + expected.append( + f"Types: {typ}\n" + f"URIs: {uri}\n" + f"Suites: {suite}\n" + f"Components: {comps}" + ) + + self.maxDiff = None + self.assertEqual(expected, list(map(str, sources.list))) + sources.save() + + expected = [ + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu\n" + "Suites: lucid lucid-updates\n" + "Components: main multiverse universe", + # unofficial suite + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu http://example.com/\n" + "Suites: notalucid\n" + "Components: main", + # unofficial mirror, FIXME: We'd rather merge the notalucid into here + "Types: deb deb-src\n" + "URIs: http://example.com/\n" + "Suites: lucid lucid-updates\n" + "Components: main", + ] + self.maxDiff = None + self.assertEqual(expected, list(map(str, sources.list))) + + def test_deb822_explode(self): + apt_pkg.config.set("Dir::Etc::sourcelist", "/dev/null") + target = ( + apt_pkg.config.find_dir("dir::etc::sourceparts") + "enable_comps.sources" + ) + line = "Types: deb\nURIs: http://archive.ubuntu.com/ubuntu\nSuites: lucid\nComponents: main\n" + with open(target, "w") as target_file: + target_file.write(line) + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + + self.assertEqual(len(sources.list), 1) + self.assertEqual(len(sources.exploded_list()), 1) + self.assertIsInstance( + sources.exploded_list()[0], aptsources.sourceslist.Deb822SourceEntry + ) + + sources.list[0].suites += ["fakesuite"] + self.assertEqual(len(sources.list), 1) + self.assertEqual(len(sources.exploded_list()), 2) + self.assertIsInstance( + sources.exploded_list()[0], aptsources.sourceslist.ExplodedDeb822SourceEntry + ) + self.assertIsInstance( + sources.exploded_list()[1], aptsources.sourceslist.ExplodedDeb822SourceEntry + ) + self.assertEqual(sources.list[0].suites, ["lucid", "fakesuite"]) + sources.remove(sources.exploded_list()[1]) + self.assertEqual(len(sources.list), 1) + self.assertEqual(len(sources.exploded_list()), 1) + self.assertEqual(sources.list[0].suites, ["lucid"]) + + sources.list[0].types += ["deb-src"] + self.assertEqual(len(sources.list), 1) + self.assertEqual(len(sources.exploded_list()), 2) + self.assertIsInstance( + sources.exploded_list()[0], aptsources.sourceslist.ExplodedDeb822SourceEntry + ) + self.assertIsInstance( + sources.exploded_list()[1], aptsources.sourceslist.ExplodedDeb822SourceEntry + ) + self.assertEqual(sources.list[0].types, ["deb", "deb-src"]) + sources.remove(sources.exploded_list()[1]) + self.assertEqual(len(sources.list), 1) + self.assertEqual(len(sources.exploded_list()), 1) + self.assertEqual(sources.list[0].types, ["deb"]) + + sources.list[0].uris += ["http://example.com"] + self.assertEqual(len(sources.list), 1) + self.assertEqual(len(sources.exploded_list()), 2) + self.assertIsInstance( + sources.exploded_list()[0], aptsources.sourceslist.ExplodedDeb822SourceEntry + ) + self.assertIsInstance( + sources.exploded_list()[1], aptsources.sourceslist.ExplodedDeb822SourceEntry + ) + self.assertEqual( + sources.list[0].uris, + ["http://archive.ubuntu.com/ubuntu", "http://example.com"], + ) + sources.remove(sources.exploded_list()[1]) + self.assertEqual(len(sources.list), 1) + self.assertEqual(len(sources.exploded_list()), 1) + self.assertEqual(sources.list[0].uris, ["http://archive.ubuntu.com/ubuntu"]) + + # test setting attributes + sources.list[0].uris += ["http://example.com"] + with self.assertRaises(AttributeError): + sources.exploded_list()[0].types = ["does not work"] + with self.assertRaises(AttributeError): + sources.exploded_list()[0].uris = ["does not work"] + with self.assertRaises(AttributeError): + sources.exploded_list()[0].suites = ["does not work"] + with self.assertRaises(AttributeError): + sources.exploded_list()[0].doesnotexist = ["does not work"] + + # test overriding + sources.exploded_list()[0].type = "faketype" + self.assertEqual(sources.list[0].type, "faketype") + self.assertEqual(sources.list[1].type, "deb") + sources.exploded_list()[0].type = "deb" + self.assertEqual(sources.list[0].type, "deb") + self.assertEqual(sources.list[1].type, "deb") + sources.save() + self.assertEqual(len(sources.list), 1) + + def testDistribution_short(self): + """aptsources: Test distribution detection.""" + apt_pkg.config.set( + "Dir::Etc::sourcelist", "data/aptsources/" "sources.list.testDistribution" + ) + return self.commonTestDistribution() + + def testDistribution_deb822(self): + """aptsources: Test distribution detection.""" + apt_pkg.config.set( + "Dir::Etc::sourceparts", + "data/aptsources/" "sources.list.d.testDistribution", + ) + return self.commonTestDistribution() + + def commonTestDistribution(self): + """aptsources: Test distribution detection.""" + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + distro = aptsources.distro.get_distro( + id="Ubuntu", + codename="bionic", + description="Ubuntu 18.04 LTS", + release="18.04", + ) + distro.get_sources(sources) + # test if all suits of the current distro were detected correctly + dist_templates = set() + for s in sources: + if s.template: + dist_templates.add(s.template.name) + # print dist_templates + for d in ( + "hardy", + "hardy-security", + "hardy-updates", + "intrepid", + "hardy-backports", + ): + self.assertTrue(d in dist_templates) + # test enable + comp = "restricted" + distro.enable_component(comp) + found = {} + for entry in sources: + if ( + entry.type == "deb" + and entry.uri == "http://de.archive.ubuntu.com/ubuntu/" + and "edgy" in entry.dist + ): + for c in entry.comps: + if c == comp: + if entry.dist not in found: + found[entry.dist] = 0 + found[entry.dist] += 1 + # print "".join([s.str() for s in sources]) + for key in found: + self.assertEqual(found[key], 1) + + # add a not-already available component + comp = "multiverse" + distro.enable_component(comp) + found = {} + for entry in sources: + if entry.type == "deb" and entry.template and entry.template.name == "edgy": + for c in entry.comps: + if c == comp: + if entry.dist not in found.has_key: + found[entry.dist] = 0 + found[entry.dist] += 1 + # print "".join([s.str() for s in sources]) + for key in found: + self.assertEqual(found[key], 1) + + @unittest.skip("lsb-release test broken when it was added") + def test_os_release_distribution(self): + """os-release file can be read and is_like is populated accordingly""" + os.environ["LSB_ETC_LSB_RELEASE"] = os.path.abspath( + "./data/aptsources/lsb-release" + ) + aptsources.distro._OSRelease.OS_RELEASE_FILE = os.path.abspath( + "./data/aptsources/os-release" + ) + distro = aptsources.distro.get_distro() + # Everything but is_like comes from lsb_release, see TODO in + # get_distro. + self.assertEqual("Ubuntu", distro.id) + self.assertEqual("xenial", distro.codename) + self.assertEqual("Ubuntu 16.04.1 LTS", distro.description) + self.assertEqual("16.04", distro.release) + self.assertEqual(["ubuntu", "debian"], distro.is_like) + + def test_enable_disabled_short(self): + """LP: #1042916: Test enabling disabled entry.""" + apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list") + return self.common_test_enable_disabled() + + def test_enable_disabled_deb822(self): + """LP: #1042916: Test enabling disabled entry.""" + apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d") + return self.common_test_enable_disabled() + + def common_test_enable_disabled(self): + """LP: #1042916: Test enabling disabled entry.""" + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + disabled = sources.add( + "deb", + "http://fi.archive.ubuntu.com/ubuntu/", + "precise", + ["main"], + file=sources.list[0].file, # if we use deb822, enable deb822 + ) + disabled.set_enabled(False) + enabled = sources.add( + "deb", + "http://fi.archive.ubuntu.com/ubuntu/", + "precise", + ["main"], + file=sources.list[0].file, # if we use deb822, enable deb822 + ) + self.assertEqual(disabled, enabled) + self.assertFalse(disabled.disabled) + + def test_duplicate_uri_with_trailing_slash_short(self): + """Test replacing entry with same uri except trailing slash""" + apt_pkg.config.set("Dir::Etc::sourcelist", "data/aptsources/" "sources.list") + return self.common_test_duplicate_uri_with_trailing_slash() + + def test_duplicate_uri_with_trailing_slash_deb822(self): + """Test replacing entry with same uri except trailing slash""" + apt_pkg.config.set("Dir::Etc::sourceparts", "data/aptsources/" "sources.list.d") + return self.common_test_duplicate_uri_with_trailing_slash() + + def common_test_duplicate_uri_with_trailing_slash(self): + """Test replacing entry with same uri except trailing slash""" + sources = aptsources.sourceslist.SourcesList(True, self.templates, deb822=True) + line_wslash = "deb http://rslash.ubuntu.com/ubuntu/ precise main" + line_woslash = "deb http://rslash.ubuntu.com/ubuntu precise main" + entry_wslash = aptsources.sourceslist.SourceEntry(line_wslash) + entry_woslash = aptsources.sourceslist.SourceEntry(line_woslash) + self.assertEqual(entry_wslash, entry_woslash) + count = len(sources.list) + sourceslist_wslash = sources.add( + entry_wslash.type, entry_wslash.uri, entry_wslash.dist, entry_wslash.comps + ) + self.assertEqual(count + 1, len(sources.list)) + count = len(sources.list) + sourceslist_woslash = sources.add( + entry_woslash.type, + entry_woslash.uri, + entry_woslash.dist, + entry_woslash.comps, + ) + self.assertEqual(count, len(sources.list)) + self.assertEqual(sourceslist_wslash, sourceslist_woslash) + + def test_deb822_distro_enable_disable_component(self): + """Test enabling and disabling a component in the distro sources. + + This ensures reasonable behavior when enabling and then disabling a component""" + with tempfile.NamedTemporaryFile("w", suffix=".sources") as file: + file.write( + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb deb-src\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + ) + file.flush() + + apt_pkg.config.set("Dir::Etc::sourcelist", file.name) + sources = aptsources.sourceslist.SourcesList( + True, self.templates, deb822=True + ) + distro = aptsources.distro.get_distro( + id="Ubuntu", + codename="noble", + description="Ubuntu 24.04 LTS", + release="24.04", + ) + + self.assertEqual(len(sources.list), 2) + distro.get_sources(sources) + distro.enable_component("multiverse") + sources.save() + + with open(file.name) as readonly: + self.maxDiff = None + self.assertEqual( + readonly.read(), + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/\n" + "Suites: noble noble-updates\n" + "Components: main universe multiverse\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb deb-src\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe multiverse\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n", + ) + + # Disable it again + # FIXME: The child entries will no longer be valid at this point, so we have to call + # get_sources(), but it's not clear whether this should be considered a bug - + # there may have been other changes rendering entries no longer valid that distro + # is holding on to. + distro.get_sources(sources) + distro.disable_component("multiverse") + sources.save() + + with open(file.name) as readonly: + self.maxDiff = None + self.assertEqual( + readonly.read(), + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb deb-src\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n", + ) + + # Disable universe as well + distro.get_sources(sources) + distro.disable_component("universe") + sources.save() + + with open(file.name) as readonly: + self.maxDiff = None + self.assertEqual( + readonly.read(), + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/\n" + "Suites: noble noble-updates\n" + "Components: main\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb deb-src\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n", + ) + + def test_deb822_distro_enable_disable_component_mixed_origin(self): + """Test enabling and disabling a component in the distro sources, with mixed origin + + Here we ensure that we still get idempotent behavior of disable after enable even if the + entry we were modifying also had a non-official repository in it.""" + with tempfile.NamedTemporaryFile("w", suffix=".sources") as file: + file.write( + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb deb-src\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + ) + file.flush() + + apt_pkg.config.set("Dir::Etc::sourcelist", file.name) + sources = aptsources.sourceslist.SourcesList( + True, self.templates, deb822=True + ) + distro = aptsources.distro.get_distro( + id="Ubuntu", + codename="noble", + description="Ubuntu 24.04 LTS", + release="24.04", + ) + + self.assertEqual(len(sources.list), 2) + distro.get_sources(sources) + distro.enable_component("multiverse") + sources.save() + + with open(file.name) as readonly: + self.maxDiff = None + self.assertEqual( + readonly.read(), + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/\n" + "Suites: noble noble-updates\n" + "Components: main universe multiverse\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://unofficial.example.com/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb deb-src\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe multiverse\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n", + ) + + # Disable it again + # FIXME: The child entries will no longer be valid at this point, so we have to call + # get_sources(), but it's not clear whether this should be considered a bug - + # there may have been other changes rendering entries no longer valid that distro + # is holding on to. + distro.get_sources(sources) + distro.disable_component("multiverse") + sources.save() + + with open(file.name) as readonly: + self.maxDiff = None + self.assertEqual( + readonly.read(), + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb deb-src\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n", + ) + + # Disable universe too. The behaviour here is interesting: Distro only disables + # universe for the official source, so we end up with the non-official source split out. + distro.get_sources(sources) + distro.disable_component("universe") + sources.save() + + with open(file.name) as readonly: + self.maxDiff = None + self.assertEqual( + readonly.read(), + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/\n" + "Suites: noble noble-updates\n" + "Components: main\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# main archive\n" # note it keeps the comment on the split out child + "Types: deb deb-src\n" + "URIs: http://unofficial.example.com/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb deb-src\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n", + ) + + def test_deb822_distro_enable_disable_child_source_mixed_origins(self): + """Test enabling and disabling a child source (proposed) in the distro sources, with mixed origin + + Here we ensure that we still get idempotent behavior of disable after enable even if the + entry we were modifying also had a non-official repository in it.""" + with tempfile.NamedTemporaryFile("w", suffix=".sources") as file: + file.write( + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb deb-src\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + ) + file.flush() + + apt_pkg.config.set("Dir::Etc::sourcelist", file.name) + sources = aptsources.sourceslist.SourcesList( + True, self.templates, deb822=True + ) + distro = aptsources.distro.get_distro( + id="Ubuntu", + codename="noble", + description="Ubuntu 24.04 LTS", + release="24.04", + ) + + self.assertEqual(len(sources.list), 2) + distro.get_sources(sources) + distro.get_source_code = True + distro.add_source(dist="noble-proposed") + + # FIXME: Component ordering is not stable right now + for entry in sources.list: + entry.comps = sorted(entry.comps) + sources.save() + + with open(file.name) as readonly: + self.maxDiff = None + + # FIXME: In an optimal world it would look like this + self.assertNotEqual( + readonly.read(), + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/\n" + "Suites: noble noble-updates noble-proposed\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://unofficial.example.com/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb deb-src\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n", + ) + + with open(file.name) as readonly: + self.maxDiff = None + # Sadly our merge algorithm does not always produce optimal merges, because it merges the unofficial entry first + self.assertEqual( + readonly.read(), + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb deb-src\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/\n" + "Suites: noble-proposed\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n", + ) + + # Disable it again + # FIXME: The child entries will no longer be valid at this point, so we have to call + # get_sources(), but it's not clear whether this should be considered a bug - + # there may have been other changes rendering entries no longer valid that distro + # is holding on to. + distro.get_sources(sources) + for child in distro.child_sources + distro.source_code_sources: + if child.dist.endswith("proposed"): + sources.remove(child) + sources.save() + + with open(file.name) as readonly: + self.maxDiff = None + self.assertEqual( + readonly.read(), + "# main archive\n" + "Types: deb deb-src\n" + "URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb deb-src\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n", + ) + + def test_deb822_distro_enable_disable_child_source_mixed_origins_no_source_code( + self, + ): + """Test enabling and disabling a child source (proposed) in the distro sources, with mixed origin + + Here we ensure that we still get idempotent behavior of disable after enable even if the + entry we were modifying also had a non-official repository in it.""" + with tempfile.NamedTemporaryFile("w", suffix=".sources") as file: + file.write( + "# main archive\n" + "Types: deb\n" + "URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + ) + file.flush() + + apt_pkg.config.set("Dir::Etc::sourcelist", file.name) + sources = aptsources.sourceslist.SourcesList( + True, self.templates, deb822=True + ) + distro = aptsources.distro.get_distro( + id="Ubuntu", + codename="noble", + description="Ubuntu 24.04 LTS", + release="24.04", + ) + + self.assertEqual(len(sources.list), 2) + distro.get_sources(sources) + self.assertEqual( + [(s.type, s.uri, s.dist, s.comps) for s in distro.main_sources] + + ["separator"] + + [(s.type, s.uri, s.dist, s.comps) for s in distro.child_sources], + [ + ( + "deb", + "http://archive.ubuntu.com/ubuntu/", + "noble", + ["main", "universe"], + ), + "separator", + ( + "deb", + "http://archive.ubuntu.com/ubuntu/", + "noble-updates", + ["main", "universe"], + ), + ( + "deb", + "http://security.ubuntu.com/ubuntu/", + "noble-security", + ["main", "universe"], + ), + ], + ) + distro.add_source(dist="noble-proposed") + + # FIXME: Component ordering is not stable right now + for entry in sources.list: + entry.comps = sorted(entry.comps) + sources.save() + + with open(file.name) as readonly: + self.maxDiff = None + + # FIXME: In an optimal world it would look like this + self.assertNotEqual( + readonly.read(), + "# main archive\n" + "Types: deb\n" + "URIs: http://archive.ubuntu.com/ubuntu/\n" + "Suites: noble noble-updates noble-proposed\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# main archive\n" + "Types: deb\n" + "URIs: http://unofficial.example.com/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n", + ) + + with open(file.name) as readonly: + self.maxDiff = None + # Sadly our merge algorithm does not always produce optimal merges, because it merges the unofficial entry first + self.assertEqual( + readonly.read(), + "# main archive\n" + "Types: deb\n" + "URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "Types: deb\n" + "URIs: http://archive.ubuntu.com/ubuntu/\n" + "Suites: noble-proposed\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n", + ) + + # Disable it again + # FIXME: The child entries will no longer be valid at this point, so we have to call + # get_sources(), but it's not clear whether this should be considered a bug - + # there may have been other changes rendering entries no longer valid that distro + # is holding on to. + distro.get_sources(sources) + for child in distro.child_sources + distro.source_code_sources: + if child.dist.endswith("proposed"): + sources.remove(child) + sources.save() + + with open(file.name) as readonly: + self.maxDiff = None + self.assertEqual( + readonly.read(), + "# main archive\n" + "Types: deb\n" + "URIs: http://archive.ubuntu.com/ubuntu/ http://unofficial.example.com/\n" + "Suites: noble noble-updates\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n" + "\n" + "# security\n" + "Types: deb\n" + "URIs: http://security.ubuntu.com/ubuntu/\n" + "Suites: noble-security\n" + "Components: main universe\n" + "Signed-By: /usr/share/keyrings/ubuntu-archive-keyrings.gpg\n", + ) + + +if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + unittest.main() diff --git a/tests/test_aptsources_deb822.py b/tests/test_aptsources_deb822.py new file mode 100755 index 0000000..6a1bb61 --- /dev/null +++ b/tests/test_aptsources_deb822.py @@ -0,0 +1,63 @@ +#!/usr/bin/python3 + +import io +import os +import tempfile +import unittest + +import apt_pkg +import testcommon + +import aptsources.distro +import aptsources.sourceslist + + +class TestAptSources(testcommon.TestCase): + def setUp(self): + testcommon.TestCase.setUp(self) + self.tempfile = tempfile.NamedTemporaryFile(suffix=".sources") + apt_pkg.config.set("Dir::Etc::sourcelist", self.tempfile.name) + apt_pkg.config.set("Dir::Etc::sourceparts", "/dev/null") + + def tearDown(self): + self.tempfile.close() + + def testEmptyDeb822(self): + """aptsources: Test sources.list parsing.""" + sources = aptsources.sourceslist.SourcesList(True) + self.assertListEqual(sources.list, []) + + def testDeb822SectionRecognizedWithoutEndLine(self): + """aptsources: Test sources.list parsing.""" + section = aptsources._deb822.Section("key: value\notherkey: othervalue") + + # Writing it back out gives us an extra newline at the end + self.assertEqual(section["key"], "value") + self.assertEqual(section["otherkey"], "othervalue") + self.assertEqual(str(section), "key: value\notherkey: othervalue\n") + + file = aptsources._deb822.File(io.StringIO("key: value\notherkey: othervalue")) + self.assertEqual(len(file.sections), 1) + + section = next(iter(file)) + self.assertEqual(section["key"], "value") + self.assertEqual(section["otherkey"], "othervalue") + self.assertEqual(str(section), "key: value\notherkey: othervalue\n") + + def testDeb822MultipleLinesSeparator(self): + """aptsources: Test sources.list parsing.""" + for separator in "\n\n\n\n", "\n\n\n", "\n\n": + with self.subTest(f"{len(separator)} separators"): + file = aptsources._deb822.File( + io.StringIO("key: value" + separator + "otherkey: othervalue\n") + ) + self.assertEqual(len(file.sections), 2) + + self.assertEqual(file.sections[0]["key"], "value") + self.assertEqual(file.sections[1]["otherkey"], "othervalue") + self.assertEqual(str(file), "key: value\n\notherkey: othervalue\n") + + +if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + unittest.main() diff --git a/tests/test_aptsources_ports.py b/tests/test_aptsources_ports.py new file mode 100644 index 0000000..234135b --- /dev/null +++ b/tests/test_aptsources_ports.py @@ -0,0 +1,41 @@ +#!/usr/bin/python3 +import os +import tempfile +import unittest + +import apt_pkg +import testcommon + +import aptsources.distro +import aptsources.sourceslist + + +class TestAptSourcesPorts(testcommon.TestCase): + """Test aptsources on ports.ubuntu.com.""" + + def setUp(self): + testcommon.TestCase.setUp(self) + apt_pkg.config.set("APT::Architecture", "powerpc") + apt_pkg.config.set("Dir::Etc", os.path.abspath("data/aptsources_ports")) + apt_pkg.config.set("Dir::Etc::sourceparts", tempfile.mkdtemp()) + if os.path.exists("../build/data/templates"): + self.templates = os.path.abspath("../build/data/templates") + else: + self.templates = "/usr/share/python-apt/templates/" + + def testMatcher(self): + """aptsources_ports: Test matcher.""" + apt_pkg.config.set("Dir::Etc::sourcelist", "sources.list") + sources = aptsources.sourceslist.SourcesList(True, self.templates) + distro = aptsources.distro.get_distro("Ubuntu", "hardy", "desc", "8.04") + distro.get_sources(sources) + # test if all suits of the current distro were detected correctly + for s in sources: + if not s.line.strip() or s.line.startswith("#"): + continue + if not s.template: + self.fail("source entry '%s' has no matcher" % s) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_auth.py b/tests/test_auth.py new file mode 100644 index 0000000..811cbb9 --- /dev/null +++ b/tests/test_auth.py @@ -0,0 +1,314 @@ +#!/usr/bin/python3 + +import contextlib +import errno +import itertools +import os +import shutil +import sys +import tempfile +import time +import unittest +from http.server import HTTPServer +from http.server import SimpleHTTPRequestHandler as HTTPRequestHandler + +import apt_pkg +import testcommon + +import apt.auth + +WHEEZY_KEYID = "8B48AD6246925553" +WHEEZY_KEYDATE = "1335553717" +WHEEZY_KEY = """-----BEGIN PGP PUBLIC KEY BLOCK----- +Version: GnuPG v1.4.12 (GNU/Linux) + +mQINBE+a7rUBEADQiEKtLOgqiq8YY/p7IFODMqGPR+o1vtXaksie8iTOh3Vxab38 +cA3kK1iB5XYElbZ5b/x3vWiufHK2semOpn5MG2GRJUwmKxZbt3HLZiHtAadkby2l +rnMxeIzfxcTxloxsQ02TMRalq89Xvy6P7lgedcW5ujcMR6JbE6uL1c/jNlkIPNuN +9paZsNJWXnZ03R+NrAJLjOPUZKZRPYgIwEci2sVNA/autsJL+HuW6X8PfldvMe5h +SdWelOoXMsZMX04JP8Efq8a09yIgKBfuXjoHJbtK0rTr9tjFKt/VM6MejLdJf4Dl +r6Zhx2ygmjcvj+FlWFoxDlPHdqfZ6mGsKR4eWDRu3bZtalDNvhZKvecwf0KaAWVU +M+GxkR+Ol3TsQ0tLbjbwZhWMioipR8Lsp6kZ1tLUjM0aOR3Mw/csyFJYKFiCo3GR +QSGY0++cDrfhQRwOJ9s2eeGGS1/I95vJZA5zZnx1ksnO0W2fHVBavICR821EBAEZ +slLzr+IOrbB16YE/aN2iA9nTcQVk69XeEh5gaeiCZ7JhA2nkAg8a/H1r4BVBC/cL +egzhUvP90kk94MmL1D2gY6UlyK4yTnHgVfjsQw6u2sPDlramyXBZehnKabIndM1P +368IbW8GTNo0gNwg/oC/vENwYnAuX+S96/O/1XfQoBNr+epTVdS4VQHICQARAQAB +tEhEZWJpYW4gQXJjaGl2ZSBBdXRvbWF0aWMgU2lnbmluZyBLZXkgKDcuMC93aGVl +enkpIDxmdHBtYXN0ZXJAZGViaWFuLm9yZz6JAj4EEwEIACgFAk+a7rUCGwMFCQ8J +nAAGCwkIBwMCBhUIAgkKCwQWAgMBAh4BAheAAAoJEItIrWJGklVTdQEQAMLCmMQr +7SxFULYgprbr5eO6uAs/8nkIBhJBzUnenOUnwsOR3Io9/sHc8Cq/xv1DTsY5G5Qj +ojywslbeF44TxBZ0j3UwPU437bfNs7yTRkgPVhHK/rZ9ApbnZdCmud+BUkDOChLV +8fzCZ17Pa5eMr5E4WI0bLM5AA3vVFLBgHFqJUgE7mSn95vA1S881/xOQ4lT1WHfa +O9K96X6ekn2zpPu/G8aq+oDyVGfo1AKQCPBJ3OCX0WB3GNWbcCb850gy9vtKlWDu +yAh1a9Cl5OPHlYqz8q+Hqj4ZeRgJiDgCgm8YAlKEooEG/vJzswaY+C3nz6uNfBeq +60QhPfgaO8qGlriChGAFqzD68ZQ53NApJw/OuwV2p5CgnkyGAVGZ1WuYcXz/wHyU +awnXq3Bf69RJssbab6SqptJyYuiY8T/2vWRgQxej18KAZ0v1Vr/MC1azp6TWgfSl +s2fvGvPf9vEbKyBR3YFa5msRKGpRauv4wWmcLfZ+jMLbSAWBfILPK+fGLtRGz4AX +hRht9rX7c4neQvlBNDDgR3tuaE3s0B1B6gTcvq7EhuuP4pAzkBLhpuzolvw+ZFOV +5mElfScYi8QbQgT9t2XjUDU1oz1ewviNhynpsxh51t5qxP5ETDGKvEx7RMv4S08p +5VGG4Y+kjcsQWfAdVAGuLqWOI0sGzUzKYZppiEYEExECAAYFAk+a8vAACgkQcV7W +oH57isk7FACcCIOIMr39LUSv16Ec9V102uheqlsAnRqdAADYF7iJIrfqyb72s/54 +3JFaiQJGBBMBCAAwBQJPmvMiBxpzdHJpbmchGmh0dHA6Ly9ncGcuZ2FubmVmZi5k +ZS9wb2xpY3kudHh0AAoJENsWz1uxJSXEhEYP/in+rib86H2vPG+ALZ35o4eh1+9P +KLtUwgHB3Wr/rmPuPY5uB02H/p3PxgJHXUXUPAleN6uajZvReO1wWLTYspPAK8ZF +6p52vuyHgOZl+VmGkLgYKOG/cckqQqTTaHwQj0O8pllJjOJYVdt5iWAHkf1N1UAA +nXC2GdxV+ZVGvZjjCDL8WFWCfoY4HznslcEHQKxg7vzZvVMTjY6L+8NmWkVoD4JL +kYtQOrId1wWYInJiQRtilyn7n9mJ+rTBSETB9Evs3x+zmNa3ntY1/U8XINgxVA5U +GYyUfUug2DjZ90LfXyZUOXVLE5yM1x7oOpyg/1mMtl5xkmuqJHOTeVEjQBYfMRHi +sS4ainR5AoD1Z5KV4S0opt198LDMXGLNjUdJEG24QEK5tfgTFRgFRJYiufxDelI3 +Aq5uGVRrBJygjwaQiJLUVlMqBGHJi++zeWr767pHVWB1XqdmPRvvOqH2v/ez4bSW +zIkUDTr947qmjyAqNNmCv/jgV5viqbj5LNslBkFg8OS+6O7na2gU5ldXfBoC0nso +3pdsCuOYUIrHyP/GjT1gvG0m+jZ/15bvoWvUv4Buh+3gYVyLwrgbq7UISRfwQEah +yzIrO5MvgS0MTIlOgO7Lxog2XMEkQ1ZCbLu5Rvm/8LC0UlSxW9aOIKBSC3hi7U8E +BuA24Mv5Iz7QvO+giQEcBBABAgAGBQJPmwDBAAoJEF7K+wCjrkSkkq8H/3M/M+Xb +vI0cY3MOkFMtyG7xmxPcny1/arnQDvjvpv1BhRBnVTstMxHWzAFQf3M8KttARWo4 +C6U5Cbc0Jx6avqXZwop91a8tQORErC9Kcrr27FJfNAOP5AVzXAofpZyXvouFYBig +ikHdRJlFrn9rydvK9Z5vg63ZzsRB7hTtHi/j1o7d0IpVmR2iTnbWGiUxpnRdLhEF +AnUU+TDFVg6EoJ6aeKsLa43UPHizq12WZPd72cJNSLMk/u+UZvg4sa7pOrkJNYN1 +jL7BSphwKCuA8vBc2lLO14uYDO8LHjd4opatMWCEEvnJQS98JytIkYcwJhJ/IgCz +tqAUo44SUcOodNGJAhwEEAECAAYFAk+bA/IACgkQvDciUsoc+WRWgA/9FYi1aqas +fJyRV4pfe90KhJ4uOO17ivnjULIDU4QFSdJpkCPznxadlDeyRbX/FhVu3RMzldIu +ZVly+VPqWwubudj9SVnqJxGkua2kEz8u3X96zif+nSB4wQuWLi4GOG9AYTnuNnZI +hO4RctYpEi9duBsPeewNi2zjUe8akhJacMhJflbW/XGsRf4goeL3WrB+k5DiDphm +nw2dge96uhZhM+Ih4hSoD9d+YLZbTqXX4L93jELE72UF4qnrZjYJtx8TSto9W2bj +sGFmpUB41viFtdnABLv5MhMsvlM37w8HTbKzzCYImgzBJNZ8Wr+VAeeQ/uB+izVv +Ls6aVKcwH2r8D+MMvh5d160lAJSUDXvZ0kdzawtBMzaNOIEYuQqoQxQGXvSAMRDV +2xFEn/XRT4iRl1stLvX86SMpLksbBfxZnrV9Q+OfTpar5O21sb1dpkgfWoF6W0kc +rjuAAsI3EbMuX3eK8r5SjWCLfIaU9ton+CdeJjJipEsEox7Rlq075t+6S4LL4wqq +dJPX4Rcuwx4LPXi9NKZAuQHisp1nuVV4luXttMdYfFq5QtokhjUaedAOORDy4gsC +mAMyLWgU/2r0grK7+AVLfn1p9wFb9FoBGFILcjVMAiY3OE5tNVPay9wGoD6n/h0O +cteh2rBrB7kEpXjRqasNfRl8vvlz7nWhTIKJAhwEEAEIAAYFAk+bAq8ACgkQEbTl +/xWw/YKuew/9Fub3t/nejgJ5KkjhfFppQQkE1yg2VJP3cbnrrhrAYZX6E6jN7dAI +MlpKqm4YR6FFe5bkra61TeXd2CI5E/MDdW4Q+AD66tA0xKRm5RzVuPvWoR9vyCx/ +fPlRuVZptwczeV5bKTFyflICV3Z/R5llq2aT6M+MZdBL4AHs5yuspkYa5f8EESi6 +pTJW0sXacjRSZyznQOZ2fMKn0LZnefSWjWoAB252hS27WW9kwpniJhUOzrrLuAWF +wnv6jfahNH14BCbNB7Q0DhcCeYnFocRv/NH8oipTrwfJ+IIMDDOcJvCbgv23w9DJ +Ynv2BaaJrbk04jux71vhaZUC0xTkE/b+rNZGnPaFnjqWBGN3s+RVZ0SHMQUzdl73 +dH3lL98mULzmf1uD7fPIrF/EYrSvFcsV7mnpFmHOd3ApY6QugmakQOLVaIpi18N4 +hJoEPBwSQ91eriieobRhjGs7LRnfmvkuQIlsQx82eycd1IV6Gp2cqzAb1qPzcaYh +TskU93Mj9OwmlqETB9FH7w7OvumQUjhHQCASeCGDeFJacZkwohWcxWkB0DUPWGgh +jnsiInTBzE/+nFsUthVlkh0Bki0BLy3gOUAgldvq3apw73OCsxjd2ORdGpFvvU2v +Xzogb+aanfTVniIfYDaJ3KHq+rF5WiVogJrK3TxsyuTAh3jFjEKNjVqJAhwEEAEI +AAYFAk+bo7wACgkQwktlomcsixJuOg/+PZqllY05fJhC5F8UzGpHDIsrokHNAc4L +xMgcudYoMwsK3NDxfXdKhfBgQqAsToSNpSYE4eNFcUF8yetdJbgoCWJOBIP1LCiy +dKXpH5mKy1PCQ+2FBb1mtKiGl1nIu1hgOx29R2ATGGSpGwbgm1Q8+cpM/nRVv7Hl +5e6uPZWkAu0MBUL9RbVSMQRpK6DUCKhLX4Loc3OS4rNjQkGnWyPtqlmU4bmRZ3R2 +INaONb4tnLkjdBhAqhgaMneEGt07nI2GBaVhdTKoI2/aDBADhuSkHomD/euiDLAF +/gqvG6ir6akBaKiaZlDyFSAdI62gQ4DZqZF0ddGcyUfyWCgAIWxBLf6RX7yDsu5L +uCT7ppkogHYpxjGdRlUhu9tBukZNqN1BEDbywUu2oHus+XjCr+AKThY2eglRTiVw +SUo6KX8xBmRoo1W32pk5t9I8uMWMVc3cVh4QhqlKmcjtTJkRIVCNCXZl5JN2Uw8q +uP6thFNCsJx6g8UwaHRXJZNKyANfe8CFGuNO0/9i8sMP/lRxmhxb5+CgZQKmCBjq +eL/TOavRJVXbilVsU4j9OFlqx9ptGHfPlfjnIq2Bf9VWJQyS6E64ecqaqc+yqaVf +hd0FMz9hq067VITuG50JeVnmSJK/EVjSgMvxWlSNinMgUjNetrkQTO9OQ0caAGFq +DHcut3Yey8o= +=id4q +-----END PGP PUBLIC KEY BLOCK-----""" + + +def normalize_key(keystr): + """Remove the Version: header from a key block""" + lines = keystr.split("\n") + if lines[1].startswith("Version:"): + return lines[:1] + lines[2:] + return lines + + +class TestAuthKeys(testcommon.TestCase): + + """Test handling of keys for signed repositories.""" + + def setUp(self): + testcommon.TestCase.setUp(self) + + self.tmpdir = tempfile.mkdtemp() + self.addCleanup(shutil.rmtree, self.tmpdir) + apt_pkg.config.set("Dir", self.tmpdir) + apt_pkg.config.set("Dir::Bin::Apt-key", "fakeroot-apt-key") + apt_pkg.config.set("Dir::Etc", "etc/apt/") + trustedparts_dir = apt_pkg.config.find_dir("Dir::Etc::Trustedparts") + confparts_dir = apt_pkg.config.find_dir("Dir::Etc::parts") + self.assertTrue(trustedparts_dir.startswith(self.tmpdir)) + os.makedirs(trustedparts_dir) + os.makedirs(confparts_dir) + shutil.copy("fakeroot-apt-key", self.tmpdir) + + @contextlib.contextmanager + def _discard_stderr(self): + stderr_fd = sys.stderr.fileno() + stderr_save = os.dup(stderr_fd) + try: + devnull = os.open("/dev/null", os.O_WRONLY) + try: + os.dup2(devnull, stderr_fd) + yield + finally: + os.close(devnull) + finally: + os.dup2(stderr_save, stderr_fd) + os.close(stderr_save) + + def testAddAndExportKey(self): + """Add an example key.""" + apt.auth.add_key(WHEEZY_KEY) + # Strip the headers from the keys to avoid test errors because + # the exported key used a differenct GnuPG version than the + # original example key + self.assertEqual( + normalize_key(apt.auth.export_key(WHEEZY_KEYID)), normalize_key(WHEEZY_KEY) + ) + + def testAddAndListKey(self): + """Add an example key and test if it is correctly returned by + list_keys() + """ + apt.auth.add_key(WHEEZY_KEY) + ret = apt.auth.list_keys() + self.assertEqual(len(ret), 1) + key = ret[0] + self.assertEqual( + key.name, + "Debian Archive Automatic Signing Key (7.0/wheezy) " + "", + ) + self.assertEqual(key.keyid, WHEEZY_KEYID) + self.assertEqual(key.date, WHEEZY_KEYDATE) + + def testAddKeyFromFile(self): + """Test adding a key from file.""" + keyfd, keyname = tempfile.mkstemp() + self.addCleanup(os.close, keyfd) + os.write(keyfd, WHEEZY_KEY.encode("UTF-8")) + + apt.auth.add_key_from_file(keyname) + + ret = apt.auth.list_keys() + self.assertEqual(len(ret), 1) + key = ret[0] + self.assertEqual( + key.name, + "Debian Archive Automatic Signing Key (7.0/wheezy) " + "", + ) + self.assertEqual(key.keyid, WHEEZY_KEYID) + self.assertEqual(key.date, WHEEZY_KEYDATE) + + def test_add_key_from_keyserver_too_short(self): + """Ensure that short keyids are not imported""" + with self.assertRaises(apt.auth.AptKeyIDTooShortError): + apt.auth.add_key_from_keyserver(WHEEZY_KEYID, "hkp://localhost:19191") + with self.assertRaises(apt.auth.AptKeyIDTooShortError): + apt.auth.add_key_from_keyserver( + "0101010178F7FE5C3E65D8AF8B48AD624692555", "hkp://localhost:19191" + ) + with self.assertRaises(apt.auth.AptKeyIDTooShortError): + apt.auth.add_key_from_keyserver( + "0x0101010178F7FE5C3E65D8AF8B48AD624692555", "hkp://localhost:19191" + ) + with self.assertRaises(apt.auth.AptKeyIDTooShortError): + apt.auth.add_key_from_keyserver( + "0101 0101 78F7 FE5C 3E65 D8AF 8B48 AD62 4692 555", + "hkp://localhost:19191", + ) + + def test_add_key_from_server_mitm(self): + """Verify that the key fingerprint is verified after download""" + self._start_keyserver() + self.addCleanup(self._stop_keyserver) + with self.assertRaises(apt.auth.AptKeyError) as cm: + with self._discard_stderr(): + apt.auth.add_key_from_keyserver( + "0101010178F7FE5C3E65D8AF8B48AD6246925553", + "hkp://localhost:%d" % self.keyserver_port, + ) + self.assertTrue( + str(cm.exception).startswith( + "recv from 'hkp://localhost:%d' failed for '%s'" + % (self.keyserver_port, "0101010178F7FE5C3E65D8AF8B48AD6246925553") + ), + cm.exception, + ) + + def testAddKeyFromServer(self): + """Install a GnuPG key from a remote server.""" + self._start_keyserver() + self.addCleanup(self._stop_keyserver) + + with self._discard_stderr(): + apt.auth.add_key_from_keyserver( + "0xa1bD8E9D78F7FE5C3E65D8AF8B48AD6246925553", + "hkp://localhost:%d" % self.keyserver_port, + ) + + ret = apt.auth.list_keys() + self.assertEqual(len(ret), 1) + key = ret[0] + self.assertEqual( + key.name, + "Debian Archive Automatic Signing Key (7.0/wheezy) " + "", + ) + self.assertEqual(key.keyid, WHEEZY_KEYID) + self.assertEqual(key.date, WHEEZY_KEYDATE) + + def _start_keyserver(self): + """Start a fake keyserver on http://localhost:19191 + If port 19191 is unavailable, try successive ports until one is. + Store the port actually in use in self.keyserver_port. + Thanks pitti. + """ + dir = tempfile.mkdtemp() + self.addCleanup(shutil.rmtree, dir) + os.mkdir(os.path.join(dir, "pks")) + with open(os.path.join(dir, "pks", "lookup"), "w") as key_file: + key_file.write(WHEEZY_KEY) + + keyserver_pipe = os.pipe() + self.keyserver_pid = os.fork() + if self.keyserver_pid == 0: + os.close(keyserver_pipe[0]) + # quiesce server log + os.dup2(os.open("/dev/null", os.O_WRONLY), sys.stderr.fileno()) + os.chdir(dir) + for port in itertools.count(19191): + try: + httpd = HTTPServer(("localhost", port), HTTPRequestHandler) + break + except OSError as e: + if e.errno != errno.EADDRINUSE: + raise + keyserver_write = os.fdopen(keyserver_pipe[1], "w") + print(port, file=keyserver_write) + keyserver_write.close() + httpd.serve_forever() + os._exit(0) + + os.close(keyserver_pipe[1]) + keyserver_read = os.fdopen(keyserver_pipe[0]) + self.keyserver_port = int(keyserver_read.readline()) + keyserver_read.close() + + # temporarily disable proxy, as gnupg does not get along with that + # (LP #789049) + self.orig_proxy = os.environ.get("http_proxy") + try: + del os.environ["http_proxy"] + except KeyError: + pass + + # wait a bit until server is ready + time.sleep(0.5) + + def _stop_keyserver(self): + """Stop fake keyserver""" + assert self.keyserver_pid + + os.kill(self.keyserver_pid, 15) + os.wait() + + # restore proxy + if self.orig_proxy is not None: + os.environ["http_proxy"] = self.orig_proxy + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_cache_invocation.py b/tests/test_cache_invocation.py new file mode 100644 index 0000000..a608034 --- /dev/null +++ b/tests/test_cache_invocation.py @@ -0,0 +1,31 @@ +#!/usr/bin/python3 +import unittest + +import apt_pkg +import testcommon + +import apt.progress.base + + +class TestCache(testcommon.TestCase): + """Test invocation of apt_pkg.Cache()""" + + def test_wrong_invocation(self): + """cache_invocation: Test wrong invocation.""" + apt_cache = apt_pkg.Cache(progress=None) + + self.assertRaises(ValueError, apt_pkg.Cache, apt_cache) + self.assertRaises( + ValueError, apt_pkg.Cache, apt.progress.base.AcquireProgress() + ) + self.assertRaises(ValueError, apt_pkg.Cache, 0) + + def test_proper_invocation(self): + """cache_invocation: Test correct invocation.""" + apt_cache = apt_pkg.Cache(progress=None) + apt_depcache = apt_pkg.DepCache(apt_cache) + self.assertNotEqual(apt_depcache, None) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_configuration.py b/tests/test_configuration.py new file mode 100644 index 0000000..c59acfa --- /dev/null +++ b/tests/test_configuration.py @@ -0,0 +1,31 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2011 Julian Andres Klode +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of apt_pkg.Configuration""" +import unittest + +import apt_pkg +import testcommon + + +class TestConfiguration(testcommon.TestCase): + """Test various configuration things""" + + def test_lp707416(self): + """configuration: Test empty arguments (LP: #707416)""" + self.assertRaises(ValueError, apt_pkg.parse_commandline, apt_pkg.config, [], []) + self.assertRaises( + SystemError, + apt_pkg.parse_commandline, + apt_pkg.config, + [], + ["cmd", "--arg0"], + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_cve_2020_27351.py b/tests/test_cve_2020_27351.py new file mode 100644 index 0000000..1ec1c76 --- /dev/null +++ b/tests/test_cve_2020_27351.py @@ -0,0 +1,149 @@ +#!/usr/bin/python +# +# Copyright (C) 2020 Canonical Ltd +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of DebFile descriptor handling.""" +import os +import sys +import unittest + +from test_all import get_library_dir + +libdir = get_library_dir() +if libdir: + sys.path.insert(0, libdir) +import gc +import subprocess +import tempfile +import warnings + +import apt_inst + + +@unittest.skipIf(not os.path.exists("/proc/self/fd"), "no /proc/self/fd available") +class TestCVE_2020_27351(unittest.TestCase): + """test the debfile""" + + GOOD_DEB = "data/test_debs/utf8-package_1.0-1_all.deb" + + def test_success(self): + """opening package successfully should not leak fd""" + before = os.listdir("/proc/self/fd") + apt_inst.DebFile(self.GOOD_DEB) + after = os.listdir("/proc/self/fd") + self.assertEqual(before, after) + + def test_regression_bug_977000(self): + """opening with a file handle should work correctly""" + with open(self.GOOD_DEB) as good_deb: + apt_inst.DebFile(good_deb).control.extractdata("control") + + def test_regression_bug_977000_2(self): + """file object <-> debfile cycles should be collected by gc.""" + + class Cycle: + def __init__(self, fname): + self.file = open(fname) + self.deb = apt_inst.DebFile(self) + + def fileno(self): + return self.file.fileno() + + before = os.listdir("/proc/self/fd") + Cycle(self.GOOD_DEB).deb.control.extractdata("control") + warnings.filterwarnings("ignore", category=ResourceWarning) + gc.collect() + warnings.resetwarnings() + after = os.listdir("/proc/self/fd") + self.assertEqual(before, after) + + def test_regression_bug_977000_2_ar(self): + """file object <-> debfile cycles should be collected by gc.""" + + class Cycle: + def __init__(self, fname): + self.file = open(fname) + self.deb = apt_inst.ArArchive(self) + + def fileno(self): + return self.file.fileno() + + before = os.listdir("/proc/self/fd") + Cycle(self.GOOD_DEB).deb.gettar("control.tar.gz", "gzip").extractdata("control") + warnings.filterwarnings("ignore", category=ResourceWarning) + gc.collect() + warnings.resetwarnings() + after = os.listdir("/proc/self/fd") + self.assertEqual(before, after) + + def test_success_a_member(self): + """fd should be kept around as long as a tarfile member""" + before = os.listdir("/proc/self/fd") + data = apt_inst.DebFile(self.GOOD_DEB).data + after = os.listdir("/proc/self/fd") + self.assertEqual(len(before), len(after) - 1) + del data + after = os.listdir("/proc/self/fd") + self.assertEqual(before, after) + + def _create_deb_without(self, member): + temp = tempfile.NamedTemporaryFile(mode="wb") + try: + with open(self.GOOD_DEB, "rb") as deb: + temp.write(deb.read()) + temp.flush() + subprocess.check_call(["ar", "d", temp.name, member]) + return temp + except Exception as e: + temp.close() + raise e + + def test_nocontrol(self): + """opening package without control.tar.gz should not leak fd""" + before = os.listdir("/proc/self/fd") + with self._create_deb_without("control.tar.gz") as temp: + try: + apt_inst.DebFile(temp.name) + except SystemError as e: + self.assertIn("control.tar", str(e)) + else: + self.fail("Did not raise an exception") + + after = os.listdir("/proc/self/fd") + self.assertEqual(before, after) + + def test_nodata(self): + """opening package without data.tar.gz should not leak fd""" + before = os.listdir("/proc/self/fd") + with self._create_deb_without("data.tar.gz") as temp: + try: + apt_inst.DebFile(temp.name) + except SystemError as e: + self.assertIn("data.tar", str(e)) + else: + self.fail("Did not raise an exception") + + after = os.listdir("/proc/self/fd") + self.assertEqual(before, after) + + def test_no_debian_binary(self): + """opening package without debian-binary should not leak fd""" + before = os.listdir("/proc/self/fd") + with self._create_deb_without("debian-binary") as temp: + try: + apt_inst.DebFile(temp.name) + except SystemError as e: + self.assertIn("missing debian-binary", str(e)) + else: + self.fail("Did not raise an exception") + + after = os.listdir("/proc/self/fd") + self.assertEqual(before, after) + + +if __name__ == "__main__": + # logging.basicConfig(level=logging.DEBUG) + unittest.main() diff --git a/tests/test_debfile.py b/tests/test_debfile.py new file mode 100644 index 0000000..bb65a94 --- /dev/null +++ b/tests/test_debfile.py @@ -0,0 +1,192 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2010 Michael Vogt +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of DebPackage in apt.debfile.""" +import logging +import os +import sys +import unittest + +from test_all import get_library_dir + +libdir = get_library_dir() +if libdir: + sys.path.insert(0, libdir) +import apt_pkg +import testcommon + +import apt.debfile + + +class TestDebfile(testcommon.TestCase): + """test the debfile""" + + TEST_DEBS = [ + # conflicts with apt + ("gdebi-test1.deb", False), + # impossible dependency + ("gdebi-test2.deb", False), + # or-group (impossible-dependency|apt) + ("gdebi-test3.deb", True), + # Conflicts: apt (<= 0.1) + ("gdebi-test4.deb", True), + # Conflicts: apt (>= 0.1) + ("gdebi-test5.deb", False), + # invalid unicode in descr + ("gdebi-test6.deb", True), + # provides/conflicts against "foobarbaz" + ("gdebi-test7.deb", True), + # provides/conflicts/replaces against "mail-transport-agent" + # (should fails if mail-transport-agent is installed) + ("gdebi-test8.deb", False), + # provides/conflicts against real pkg + ("gdebi-test9.deb", True), + # provides debconf-tiny and the real debconf conflicts with + ("gdebi-test10.deb", False), + ] + + def setUp(self): + testcommon.TestCase.setUp(self) + apt_pkg.config.set("APT::Architecture", "i386") + # FIXME: When run via test_all.py, the tests fail without this if it + # is set in the system. + apt_pkg.config.clear("APT::Architectures") + apt_pkg.config.set("Dir::State::status", "./data/test_debs/var/lib/dpkg/status") + apt_pkg.config.set("Dir::State::lists", "./data/test_debs/var/lib/apt/lists") + apt_pkg.config.set( + "Dir::Etc::sourcelist", "./data/test_debs/etc/apt/sources.list" + ) + apt_pkg.init_system() + self.cache = apt.Cache() + + def test_dsc_file(self): + filename = "hello_2.5-1.dsc" + deb = apt.debfile.DscSrcPackage(cache=self.cache) + deb.open(os.path.join("data", "test_debs", filename)) + self.assertTrue(deb.check(), "got failure '%s'" % deb._failure_string) + missing = {"autotools-dev"} + self.assertEqual(set(deb.missing_deps), missing) + # specialized properties + self.assertEqual(deb.pkgname, "hello") + self.assertEqual(deb.binaries, ["hello", "bello", "cello"]) + self.assertEqual(deb.filelist, ["hello_2.5.orig.tar.gz", "hello_2.5-1.diff.gz"]) + self.assertEqual(deb.depends, [[("autotools-dev", "", "")]]) + # tag fields are available as a dict + self.assertEqual(deb["Format"], "1.0") + self.assertEqual(deb["Source"], "hello") + self.assertEqual(deb["Binary"], "hello, bello,\n cello") + self.assertEqual(deb["Architecture"], "any") + self.assertEqual(deb["Version"], "2.5-1") + self.assertEqual(deb["Maintainer"], "Santiago Vila ") + self.assertEqual(deb["Homepage"], "http://www.gnu.org/software/hello") + self.assertEqual(deb["Standards-Version"], "3.8.4") + + def test_dsc_file_with_impossible_build_dep(self): + filename = "impossible-build-depends_2.5-1.dsc" + deb = apt.debfile.DscSrcPackage(cache=self.cache) + deb.open(os.path.join("data", "test_debs", filename)) + self.assertFalse(deb.check()) + self.assertEqual(deb.depends, [[("debhelper", "101", ">")]]) + + def test_deb_file(self): + deb = apt.debfile.DebPackage(cache=self.cache) + for filename, expected_res in self.TEST_DEBS: + logging.debug(f"testing {filename}, expecting {expected_res}") + deb.open(os.path.join("data", "test_debs", filename)) + res = deb.check() + self.assertEqual( + res, + expected_res, + "Unexpected result for package '%s' (got %s wanted %s)\n%s" + % (filename, res, expected_res, deb._failure_string), + ) + + def test_utf8_sections(self): + deb = apt.debfile.DebPackage(cache=self.cache) + deb.open(os.path.join("data", "test_debs", "utf8-package_1.0-1_all.deb")) + self.assertEqual(deb["Maintainer"], "Samuel Lidén Borell ") + + def test_content(self): + # normal + deb = apt.debfile.DebPackage(cache=self.cache) + deb.open(os.path.join("data", "test_debs", "gdebi-test11.deb")) + self.assertEqual('#!/bin/sh\necho "test"\n', deb.data_content("usr/bin/test")) + # binary + deb = apt.debfile.DebPackage(cache=self.cache) + deb.open(os.path.join("data", "test_debs", "gdebi-test12.deb")) + content = deb.data_content("usr/bin/binary") + self.assertTrue( + content.startswith("Automatically converted to printable ascii:\n\x7fELF ") + ) + # control file + needle = """Package: gdebi-test12 +Version: 1.0 +Architecture: all +Description: testpackage for gdebi - contains usr/bin/binary for file reading + This tests the binary file reading for debfile.py +""" + content = deb.control_content("./control") + self.assertEqual(content, needle) + content = deb.control_content("control") + self.assertEqual(content, needle) + + def test_xz_data(self): + deb = apt.debfile.DebPackage("./data/test_debs/data-tar-xz.deb") + self.assertEqual(deb.filelist, ["./", "usr/", "usr/bin/"]) + + @unittest.skipIf( + apt_pkg.version_compare(apt_pkg.VERSION, "0.9.15.4~") < 0, + "APT too old for uncompressed control.tar/data.tar", + ) + def test_uncompressed_data(self): + deb = apt.debfile.DebPackage("./data/test_debs/data-tar.deb") + self.assertEqual(deb.filelist, ["./", "usr/", "usr/bin/"]) + + def test_check_exception(self): + deb = apt.debfile.DebPackage("./data/test_debs/data-tar-xz.deb") + self.assertRaises(AttributeError, lambda: deb.missing_deps) + deb.check() + deb.missing_deps + + def test_no_supported_data_tar(self): + with self.assertRaises(SystemError): + apt.debfile.DebPackage("./data/test_debs/data-tar-broken.deb") + + def test_contains(self): + deb = apt.debfile.DebPackage("./data/test_debs/data-tar-xz.deb") + self.assertTrue("Package" in deb) + + def test_multi_arch_allowed(self): + apt_pkg.config["APT::Architectures::"] = "i386" + apt_pkg.config["APT::Architectures::"] = "amd64" + apt_pkg.config["APT::Architecture"] = "amd64" + apt_pkg.init_system() + + allowed_any = apt.debfile.DebPackage( + "./data/test_debs/testdep-allowed-any_1.0-1_i386.deb" + ) + self.assertTrue(allowed_any.check(), allowed_any._failure_string) + + def test_multi_arch_same(self): + apt_pkg.config["APT::Architectures::"] = "i386" + apt_pkg.config["APT::Architectures::"] = "amd64" + apt_pkg.config["APT::Architecture"] = "amd64" + apt_pkg.init_system() + same = apt.debfile.DebPackage( + "./data/test_debs/testdep-same-arch_1.0-1_i386.deb" + ) + self.assertTrue(same.check(), same._failure_string) + + def test_get_content_gzip_data(self): + deb = apt.debfile.DebPackage("./data/test_debs/gdebi-test13.deb") + data = deb.data_content("./lala.gz") + self.assertEqual(data, "Automatically decompressed:\n\nlala\n") + + +if __name__ == "__main__": + # logging.basicConfig(level=logging.DEBUG) + unittest.main() diff --git a/tests/test_debfile_multiarch.py b/tests/test_debfile_multiarch.py new file mode 100644 index 0000000..24f0265 --- /dev/null +++ b/tests/test_debfile_multiarch.py @@ -0,0 +1,63 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2010 Michael Vogt +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of DebPackage in apt.debfile.""" +import sys +import unittest + +from test_all import get_library_dir + +libdir = get_library_dir() +if libdir: + sys.path.insert(0, libdir) +import apt_pkg +import testcommon + +import apt +import apt.debfile + + +class TestDebfileMultiarch(testcommon.TestCase): + """test the multiarch debfile""" + + def test_multiarch_deb_check(self): + if apt_pkg.get_architectures() != ["amd64", "i386"]: + # TODO: use unittest.skip + # logging.warning("skipping test because running on a " + # "non-multiarch system") + return + deb = apt.debfile.DebPackage("./data/test_debs/multiarch-test1_i386.deb") + deb.check() + missing = deb.missing_deps + # print missing + self.assertFalse("dpkg:i386" in missing) + + @unittest.skip("BROKEN, lib3ds-1-3 is m-a now") + def test_multiarch_conflicts(self): + cache = apt.Cache() + # WARNING: this assumes that lib3ds-1-3 is a non-multiarch lib + # use "lib3ds-1-3" as a test to see if non-multiach lib conflicts work + canary = "lib3ds-1-3" + if canary not in cache: + # TODO: use unittest.skip + # logging.warning("skipping test because %s is missing" % canary) + return + cache[canary].mark_install() + deb = apt.debfile.DebPackage( + "./data/test_debs/multiarch-test1_i386.deb", cache=cache + ) + # this deb should now not be installable + installable = deb.check() + # print deb._failure_string + self.assertFalse(installable) + self.assertEqual( + deb._failure_string, "Conflicts with the installed package 'lib3ds-1-3'" + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_deps.py b/tests/test_deps.py new file mode 100644 index 0000000..860856c --- /dev/null +++ b/tests/test_deps.py @@ -0,0 +1,142 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2010 Julian Andres Klode +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of check_dep, etc in apt_pkg.""" +import itertools +import unittest + +import apt_pkg +import testcommon + +import apt.package + + +class TestDependencies(testcommon.TestCase): + def testCheckDep(self): + """dependencies: Test apt_pkg.CheckDep() for '<' and '>' + + The CheckDep function should treat '<' as '<=' and '>' as '>=', for + compatibility reasons.""" + if not hasattr(apt_pkg, "CheckDep"): + return + self.assertFalse(apt_pkg.CheckDep("1", "<", "0")) + self.assertTrue(apt_pkg.CheckDep("1", "<", "1")) + self.assertTrue(apt_pkg.CheckDep("1", "<", "2")) + + self.assertFalse(apt_pkg.CheckDep("0", ">", "1")) + self.assertTrue(apt_pkg.CheckDep("1", ">", "1")) + self.assertTrue(apt_pkg.CheckDep("2", ">", "1")) + + def test_check_dep(self): + "dependencies: Test apt_pkg.check_dep()" + self.assertFalse(apt_pkg.check_dep("1", "<<", "0")) + self.assertFalse(apt_pkg.check_dep("1", "<<", "1")) + self.assertTrue(apt_pkg.check_dep("1", "<<", "2")) + + self.assertFalse(apt_pkg.check_dep("1", "<", "0")) + self.assertFalse(apt_pkg.check_dep("1", "<", "1")) + self.assertTrue(apt_pkg.check_dep("1", "<", "2")) + + self.assertFalse(apt_pkg.check_dep("1", "<=", "0")) + self.assertTrue(apt_pkg.check_dep("1", "<=", "1")) + self.assertTrue(apt_pkg.check_dep("1", "<=", "2")) + + self.assertFalse(apt_pkg.check_dep("0", "=", "1")) + self.assertTrue(apt_pkg.check_dep("1", "=", "1")) + self.assertFalse(apt_pkg.check_dep("2", "=", "1")) + + self.assertFalse(apt_pkg.check_dep("0", ">=", "1")) + self.assertTrue(apt_pkg.check_dep("1", ">=", "1")) + self.assertTrue(apt_pkg.check_dep("2", ">=", "1")) + + self.assertFalse(apt_pkg.check_dep("0", ">", "1")) + self.assertFalse(apt_pkg.check_dep("1", ">", "1")) + self.assertTrue(apt_pkg.check_dep("2", ">", "1")) + + self.assertFalse(apt_pkg.check_dep("0", ">>", "1")) + self.assertFalse(apt_pkg.check_dep("1", ">>", "1")) + self.assertTrue(apt_pkg.check_dep("2", ">>", "1")) + + def test_parse_depends_multiarch(self): + # strip multiarch + deps = apt_pkg.parse_depends("po4a:native", True) + self.assertEqual(deps[0][0][0], "po4a") + # do not strip multiarch + deps = apt_pkg.parse_depends("po4a:native", False) + self.assertEqual(deps[0][0][0], "po4a:native") + + def test_parse_depends(self): + """dependencies: Test apt_pkg.parse_depends()""" + deps = apt_pkg.parse_depends("p1a (<< 1a) | p1b (>> 1b)") + self.assertTrue(isinstance(deps, list)) + self.assertEqual(len(deps), 1) + self.assertTrue(isinstance(deps[0], list)) + self.assertEqual(len(deps[0]), 2) + self.assertEqual(len(deps[0][0]), 3) + self.assertEqual(len(deps[0][1]), 3) + self.assertEqual(deps[0][0][0], "p1a") + self.assertEqual(deps[0][0][1], "1a") + self.assertEqual(deps[0][0][2], "<") + self.assertEqual(deps[0][1][0], "p1b") + self.assertEqual(deps[0][1][1], "1b") + self.assertEqual(deps[0][1][2], ">") + + # Check that the type of comparison is parsed correctly. + self.assertEqual("<", apt_pkg.parse_depends("p1 (<< 1)")[0][0][2]) + self.assertEqual("<=", apt_pkg.parse_depends("p1 (< 1)")[0][0][2]) + self.assertEqual("<=", apt_pkg.parse_depends("p1 (<= 1)")[0][0][2]) + self.assertEqual("=", apt_pkg.parse_depends("p1 (= 1)")[0][0][2]) + self.assertEqual(">=", apt_pkg.parse_depends("p1 (>= 1)")[0][0][2]) + self.assertEqual(">=", apt_pkg.parse_depends("p1 (> 1)")[0][0][2]) + self.assertEqual(">", apt_pkg.parse_depends("p1 (>> 1)")[0][0][2]) + + def test_parse_src_depends(self): + """dependencies: Test apt_pkg.parse_src_depends().""" + # Check that architecture exclusion works + # depends_this: Current architecture is included + # depends_this_too: Another architecture is excluded + # depends_other: The current architecture is excluded + # depends_other: Another architecture is requested. + architecture = apt_pkg.config["APT::Architecture"] + depends_this = apt_pkg.parse_src_depends("p [%s]" % architecture) + depends_this_too = apt_pkg.parse_src_depends("p [!not-existing-arch]") + depends_other = apt_pkg.parse_src_depends("p [!%s]" % architecture) + depends_other_too = apt_pkg.parse_src_depends("p [not-existing-arch]") + + self.assertEqual(len(depends_this), len(depends_this_too), 1) + self.assertEqual(len(depends_other), len(depends_other_too), 0) + + def test_dstr(self): + """Test apt.package.BaseDependency.__dstr""" + dstr = apt.package.BaseDependency._BaseDependency__dstr + equal = {"<": {"<<", "<"}, "=": {"==", "="}, ">": {">>", ">"}} + operators = ["<<", "<", "<=", "!=", "=", "==", ">=", ">", ">>"] + + for a, b in itertools.product(equal.keys(), operators): + if b in equal[a]: + self.assertEqual(dstr(a), b) + self.assertEqual(b, dstr(a)) + else: + self.assertNotEqual(dstr(a), b) + self.assertNotEqual(b, dstr(a)) + + def testParseDepends(self): + """dependencies: Test apt_pkg.ParseDepends().""" + if not hasattr(apt_pkg, "ParseDepends"): + return + # Check that the type of comparison is parsed correctly. + self.assertEqual("<<", apt_pkg.ParseDepends("p1 (<< 1)")[0][0][2]) + self.assertEqual("<=", apt_pkg.ParseDepends("p1 (< 1)")[0][0][2]) + self.assertEqual("<=", apt_pkg.ParseDepends("p1 (<= 1)")[0][0][2]) + self.assertEqual("=", apt_pkg.ParseDepends("p1 (= 1)")[0][0][2]) + self.assertEqual(">=", apt_pkg.ParseDepends("p1 (>= 1)")[0][0][2]) + self.assertEqual(">=", apt_pkg.ParseDepends("p1 (> 1)")[0][0][2]) + self.assertEqual(">>", apt_pkg.ParseDepends("p1 (>> 1)")[0][0][2]) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_group.py b/tests/test_group.py new file mode 100644 index 0000000..d08ed06 --- /dev/null +++ b/tests/test_group.py @@ -0,0 +1,31 @@ +import unittest + +import apt_pkg +import testcommon + + +class TestGroup(testcommon.TestCase): + def setUp(self): + testcommon.TestCase.setUp(self) + self.cache = apt_pkg.Cache(progress=None) + + def test_pkgingroup(self): + """Check that each package belongs to the corresponding group""" + for pkg in self.cache.packages: + group = apt_pkg.Group(self.cache, pkg.name) + assert any(pkg.id == p.id for p in group) + + def test_iteration(self): + """Check that iteration works correctly.""" + for pkg in self.cache.packages: + group = apt_pkg.Group(self.cache, pkg.name) + + list(group) == list(group) + + def test_cache_groups(self): + """group: Iterate over all groups""" + assert len(list(self.cache.groups)) == self.cache.group_count + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_hashes.py b/tests/test_hashes.py new file mode 100644 index 0000000..d322a1f --- /dev/null +++ b/tests/test_hashes.py @@ -0,0 +1,206 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2009 Julian Andres Klode +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of hashsums in apt_pkg. + +Unit tests to verify the correctness of Hashes, HashString and the various +functions like md5sum.""" +import hashlib +import unittest +import warnings + +import apt_pkg +import testcommon + + +class TestHashes(testcommon.TestCase): + """Test apt_pkg.Hashes() and the various apt_pkg.*sum() functions.""" + + def setUp(self): + """Prepare the tests, create reference values...""" + testcommon.TestCase.setUp(self) + self.file = open(apt_pkg.__file__, "rb") + self.value = self.file.read() + self.hashes = apt_pkg.Hashes(self.value) + self.file.seek(0) + self.fhashes = apt_pkg.Hashes(self.file) + # Reference values. + self.md5 = hashlib.md5(self.value).hexdigest() + self.sha1 = hashlib.sha1(self.value).hexdigest() + self.sha256 = hashlib.sha256(self.value).hexdigest() + self.file.seek(0) + + warnings.filterwarnings("ignore", category=DeprecationWarning) + + def tearDown(self): + """Cleanup, Close the file object used for the tests.""" + testcommon.TestCase.tearDown(self) + warnings.resetwarnings() + self.file.close() + + def test_md5sum(self): + """hashes: Test apt_pkg.md5sum()""" + self.assertEqual(apt_pkg.md5sum(self.value), self.md5) + self.assertEqual(apt_pkg.md5sum(self.file), self.md5) + + def test_sha1sum(self): + """hashes: Test apt_pkg.sha1sum()""" + self.assertEqual(apt_pkg.sha1sum(self.value), self.sha1) + self.assertEqual(apt_pkg.sha1sum(self.file), self.sha1) + + def test_sha256sum(self): + """hashes: Test apt_pkg.sha256sum()""" + self.assertEqual(apt_pkg.sha256sum(self.value), self.sha256) + self.assertEqual(apt_pkg.sha256sum(self.file), self.sha256) + + def test_bytes(self): + """hashes: Test apt_pkg.Hashes(bytes)""" + self.assertEqual(self.hashes.hashes.find("md5sum").hashvalue, self.md5) + self.assertEqual( + self.hashes.hashes.find("md5sum"), apt_pkg.HashString("MD5Sum", self.md5) + ) + self.assertEqual( + self.hashes.hashes.find("sha1"), apt_pkg.HashString("SHA1", self.sha1) + ) + self.assertEqual( + self.hashes.hashes.find("sha256"), apt_pkg.HashString("SHA256", self.sha256) + ) + self.assertRaises(KeyError, self.hashes.hashes.find, "md5") + + def test_file(self): + """hashes: Test apt_pkg.Hashes(file).""" + self.assertEqual(self.fhashes.hashes.find("md5sum").hashvalue, self.md5) + self.assertEqual( + self.fhashes.hashes.find("md5sum"), apt_pkg.HashString("MD5Sum", self.md5) + ) + self.assertEqual( + self.fhashes.hashes.find("sha1"), apt_pkg.HashString("SHA1", self.sha1) + ) + self.assertEqual( + self.fhashes.hashes.find("sha256"), + apt_pkg.HashString("SHA256", self.sha256), + ) + + def test_unicode(self): + """hashes: Test apt_pkg.Hashes(unicode).""" + self.assertRaises(TypeError, apt_pkg.Hashes, "D") + self.assertRaises(TypeError, apt_pkg.md5sum, "D") + self.assertRaises(TypeError, apt_pkg.sha1sum, "D") + self.assertRaises(TypeError, apt_pkg.sha256sum, "D") + + +class TestHashString(testcommon.TestCase): + """Test apt_pkg.HashString().""" + + def setUp(self): + """Prepare the test by reading the file.""" + testcommon.TestCase.setUp(self) + self.file = open(apt_pkg.__file__) + self.hashes = apt_pkg.Hashes(self.file) + + self.md5 = self.hashes.hashes.find("md5sum") + self.sha1 = self.hashes.hashes.find("sha1") + self.sha256 = self.hashes.hashes.find("sha256") + + def tearDown(self): + """Cleanup, Close the file object used for the tests.""" + self.file.close() + + def test_md5(self): + """hashes: Test apt_pkg.HashString().md5""" + self.assertIn("MD5Sum:", str(self.md5)) + self.assertTrue(self.md5.verify_file(apt_pkg.__file__)) + + def test_sha1(self): + """hashes: Test apt_pkg.HashString().sha1""" + self.assertIn("SHA1:", str(self.sha1)) + self.assertTrue(self.sha1.verify_file(apt_pkg.__file__)) + + def test_sha256(self): + """hashes: Test apt_pkg.HashString().sha256""" + self.assertIn("SHA256:", str(self.sha256)) + self.assertTrue(self.sha256.verify_file(apt_pkg.__file__)) + + def test_wrong(self): + """hashes: Test apt_pkg.HashString(wrong_type).""" + self.assertRaises(TypeError, apt_pkg.HashString, 0) + self.assertRaises(TypeError, apt_pkg.HashString, b"") + + +class TestHashStringList(testcommon.TestCase): + """Test apt_pkg.HashStringList()""" + + def test_file_size(self): + hsl = apt_pkg.HashStringList() + self.assertEqual(hsl.file_size, 0) + hsl.file_size = 42 + self.assertEqual(hsl.file_size, 42) + self.assertEqual(len(hsl), 1) + + # Verify that I can re-assign value (this handles the long case on + # Python 2). + hsl.file_size = hsl.file_size + + with self.assertRaises(OverflowError): + hsl.file_size = -1 + + hsl.file_size = 0 + + def test_append(self): + """Testing whether append works correctly.""" + hs1 = apt_pkg.HashString("MD5Sum", "a60599e6200b60050d7a30721e3532ed") + hs2 = apt_pkg.HashString("SHA1", "ef113338e654b1ada807a939ad47b3a67633391b") + + hsl = apt_pkg.HashStringList() + hsl.append(hs1) + hsl.append(hs2) + self.assertEqual(len(hsl), 2) + self.assertEqual(hsl[0].hashtype, "MD5Sum") + self.assertEqual(hsl[1].hashtype, "SHA1") + self.assertEqual(str(hsl[0]), str(hs1)) + self.assertEqual(str(hsl[1]), str(hs2)) + + def test_find(self): + """Testing whether append works correctly.""" + hs1 = apt_pkg.HashString("MD5Sum", "a60599e6200b60050d7a30721e3532ed") + hs2 = apt_pkg.HashString("SHA1", "ef113338e654b1ada807a939ad47b3a67633391b") + + hsl = apt_pkg.HashStringList() + hsl.append(hs1) + hsl.append(hs2) + + self.assertEqual(hsl.find("MD5Sum").hashtype, "MD5Sum") + self.assertEqual(hsl.find("SHA1").hashtype, "SHA1") + self.assertEqual(hsl.find().hashtype, "SHA1") + + def test_verify_file(self): + with open(apt_pkg.__file__) as fobj: + hashes = apt_pkg.Hashes(fobj) + with warnings.catch_warnings(record=True): + warnings.simplefilter("always") + sha1 = hashes.hashes.find("sha1") + sha256 = hashes.hashes.find("sha256") + + hsl = apt_pkg.HashStringList() + hsl.append(sha1) + hsl.append(sha256) + + self.assertTrue(hsl.verify_file(apt_pkg.__file__)) + + md5sum = apt_pkg.HashString("MD5Sum", "a60599e6200b60050d7a30721e3532ed") + hsl.append(md5sum) + + self.assertFalse(hsl.verify_file(apt_pkg.__file__)) + + hsl2 = hashes.hashes + self.assertIsInstance(hsl2, apt_pkg.HashStringList) + self.assertGreater(len(hsl2), 0) + self.assertTrue(hsl2.verify_file(apt_pkg.__file__)) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_hashsums.py b/tests/test_hashsums.py new file mode 100644 index 0000000..1d7cc0e --- /dev/null +++ b/tests/test_hashsums.py @@ -0,0 +1,106 @@ +#!/usr/bin/python3 + +import unittest +import warnings + +import apt_pkg +import testcommon + + +class testHashes(testcommon.TestCase): + "test the hashsum functions against strings and files" + + DATA_PATH = "data/hashsums/hashsum_test.data" + DATA_WITH_ZERO_PATH = "data/hashsums/hashsum_test_with_zero.data" + + def setUp(self): + testcommon.TestCase.setUp(self) + warnings.filterwarnings("ignore", category=DeprecationWarning) + + def tearDown(self): + testcommon.TestCase.tearDown(self) + warnings.resetwarnings() + + def testMD5(self): + # simple + s = b"foo" + s_md5 = "acbd18db4cc2f85cedef654fccc4a4d8" + res = apt_pkg.md5sum(s) + self.assertEqual(res, s_md5) + # file + with open(self.DATA_PATH) as fobj: + self.assertEqual(apt_pkg.md5sum(fobj), s_md5) + # with zero (\0) in the string + s = b"foo\0bar" + s_md5 = "f6f5f8cd0cb63668898ba29025ae824e" + res = apt_pkg.md5sum(s) + self.assertEqual(res, s_md5) + # file + with open(self.DATA_WITH_ZERO_PATH) as fobj: + self.assertEqual(apt_pkg.md5sum(fobj), s_md5) + + def testSHA1(self): + # simple + s = b"foo" + s_hash = "0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33" + res = apt_pkg.sha1sum(s) + self.assertEqual(res, s_hash) + # file + with open(self.DATA_PATH) as fobj: + self.assertEqual(apt_pkg.sha1sum(fobj), s_hash) + # with zero (\0) in the string + s = b"foo\0bar" + s_hash = "e2c300a39311a2dfcaff799528415cb74c19317f" + res = apt_pkg.sha1sum(s) + self.assertEqual(res, s_hash) + # file + with open(self.DATA_WITH_ZERO_PATH) as fobj: + self.assertEqual(apt_pkg.sha1sum(fobj), s_hash) + + def testSHA256(self): + # simple + s = b"foo" + s_hash = "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae" + res = apt_pkg.sha256sum(s) + self.assertEqual(res, s_hash) + # file + with open(self.DATA_PATH) as fobj: + self.assertEqual(apt_pkg.sha256sum(fobj), s_hash) + # with zero (\0) in the string + s = b"foo\0bar" + s_hash = "d6b681bfce7155d44721afb79c296ef4f0fa80a9dd6b43c5cf74dd0f64c85512" + res = apt_pkg.sha256sum(s) + self.assertEqual(res, s_hash) + # file + with open(self.DATA_WITH_ZERO_PATH) as fobj: + self.assertEqual(apt_pkg.sha256sum(fobj), s_hash) + + def testSHA512(self): + # simple + s = b"foo" + s_hash = ( + "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d" + "0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19" + "594a7eb539453e1ed7" + ) + res = apt_pkg.sha512sum(s) + self.assertEqual(res, s_hash) + # file + with open(self.DATA_PATH) as fobj: + self.assertEqual(apt_pkg.sha512sum(fobj), s_hash) + # with zero (\0) in the string + s = b"foo\0bar" + s_hash = ( + "8c5e791db8f6bfb40eba884f70c9ac52231f01a393e4e55b4576d45" + "9a827f34f77e41e7fac806724517b9e96bb42387c5f9bbf325d2f99" + "ed52a4aa6abebc3350" + ) + res = apt_pkg.sha512sum(s) + self.assertEqual(res, s_hash) + # file + with open(self.DATA_WITH_ZERO_PATH) as fobj: + self.assertEqual(apt_pkg.sha512sum(fobj), s_hash) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_install_progress_exec.py b/tests/test_install_progress_exec.py new file mode 100644 index 0000000..064eb81 --- /dev/null +++ b/tests/test_install_progress_exec.py @@ -0,0 +1,43 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2019 Colomban Wendling +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying InstallProgress works when spawning dpkg directly +(i.e. when installing standalone .debs).""" +import os +import sys +import unittest + +from test_all import get_library_dir + +libdir = get_library_dir() +if libdir: + sys.path.insert(0, libdir) +import testcommon + +from apt.progress.base import InstallProgress + + +class RunHelper: + def __init__(self): + self.script = "helper_install_progress_run.py" + + def do_install(self, fd): + return os.spawnl(os.P_WAIT, self.script, self.script, str(fd)) + + +class TestInstallProgressExec(testcommon.TestCase): + """test that InstallProgress.run() passes a valid file descriptor to + a child process""" + + def test_run(self): + with InstallProgress() as prog: + self.assertEqual(prog.run(RunHelper()), 0) + + +if __name__ == "__main__": + os.chdir(os.path.dirname(__file__)) + unittest.main() diff --git a/tests/test_large_file.py b/tests/test_large_file.py new file mode 100644 index 0000000..87bc9b6 --- /dev/null +++ b/tests/test_large_file.py @@ -0,0 +1,25 @@ +#!/usr/bin/python3 + +import sys +import unittest + +import apt_inst +import testcommon + +IS_NOT_32BIT = sys.maxsize > 2**32 + + +@unittest.skipIf(IS_NOT_32BIT, "Large File support is for 32 bit systems") +class testHashes(testcommon.TestCase): + "test the hashsum functions against strings and files" + + LARGE_PACKAGE_CONTENT = "data/test_debs/large-package-content_1.0_all.deb" + + def testExtractData(self): + deb = apt_inst.DebFile(self.LARGE_PACKAGE_CONTENT) + + self.assertRaises(MemoryError, deb.data.extractdata, "large-file") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_lfs.py b/tests/test_lfs.py new file mode 100644 index 0000000..d82e762 --- /dev/null +++ b/tests/test_lfs.py @@ -0,0 +1,19 @@ +#!/usr/bin/python3 +import unittest + +import apt_pkg +import testcommon + + +class TestLargeFileSupport(testcommon.TestCase): + """Test large file support""" + + def test_acquire_file(self): + """Test apt_pkg.AcquireFile() accepts large file size""" + acq = apt_pkg.Acquire() + fil = apt_pkg.AcquireFile(acq, "http://foo", "foo", size=2875204834) + self.assertEqual(fil.filesize, 2875204834) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_lp659438.py b/tests/test_lp659438.py new file mode 100644 index 0000000..21ad061 --- /dev/null +++ b/tests/test_lp659438.py @@ -0,0 +1,80 @@ +#!/usr/bin/python3 +"""Regression test for LP: #981896, LP: #659438""" +# Copyright (C) 2012 Sebastian Heinlein +# +# 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. +# Licensed under the GNU General Public License Version 2 + +__author__ = "Sebastian Heinlein " + +import os +import shutil +import tempfile +import unittest + +import apt_pkg +import testcommon + +import apt + + +class RegressionTestCase(testcommon.TestCase): + + """Test suite for LP: #981896, LP: #659438 + 'Cannot locate a file for package X' + """ + + def setUp(self): + testcommon.TestCase.setUp(self) + apt_pkg.config.clear("APT::Update::Post-Invoke") + apt_pkg.config.clear("APT::Update::Post-Invoke-Success") + self.chroot_path = chroot_path = tempfile.mkdtemp() + # Create a damaged status file + self.cache = apt.cache.Cache(rootdir=chroot_path) + with open(apt_pkg.config.find_file("Dir::State::status"), "a") as status: + status.write( + """Package: abrowser +Status: install reinstreq half-installed +Priority: optional +Section: admin +Version: 3.6.9+build1+nobinonly-0ubuntu1 +Architecture: all""" + ) + sources_list_path = apt_pkg.config.find_file("Dir::Etc::sourcelist") + repo_path = os.path.abspath("./data/test-repo") + with open(sources_list_path, "w") as sources_list: + sources_list.write("deb [allow-insecure=yes] copy:%s /\n" % repo_path) + # os.makedirs(os.path.join(chroot_path, "etc/apt/sources.list.d/")) + self.cache.update(sources_list=sources_list_path) + self.cache.open() + + def tearDown(self): + # this resets the rootdir apt_pkg.config to ensure it does not + # "pollute" the later tests + apt.cache.Cache(rootdir="/") + shutil.rmtree(self.chroot_path) + + def test_survive_reqreinst(self): + """Test that we survive a package in require reinstallation state""" + # this should be 82324L but python3.2 gets unhappy about the "L" + self.assertEqual(self.cache.required_download, 82324) + + +if __name__ == "__main__": + unittest.main() + +# vim: ts=4 et sts=4 diff --git a/tests/test_paths.py b/tests/test_paths.py new file mode 100644 index 0000000..4920a25 --- /dev/null +++ b/tests/test_paths.py @@ -0,0 +1,158 @@ +# +# Test that both unicode and bytes path names work +# +import os +import shutil +import unittest + +import apt_inst +import apt_pkg +import testcommon + + +class TestPath(testcommon.TestCase): + dir_unicode = "data/tmp" + dir_bytes = b"data/tmp" + file_unicode = "data/tmp/python-apt-test" + file_bytes = b"data/tmp/python-apt-test" + + def setUp(self): + testcommon.TestCase.setUp(self) + if os.path.exists(self.dir_bytes): + shutil.rmtree(self.dir_bytes) + + os.mkdir(self.dir_bytes) + + def tearDown(self): + apt_pkg.config["dir"] = "/" + shutil.rmtree(self.dir_bytes) + + def test_acquire(self): + apt_pkg.AcquireFile( + apt_pkg.Acquire(), + "http://example.com", + destdir=self.file_bytes, + destfile=self.file_bytes, + ) + apt_pkg.AcquireFile( + apt_pkg.Acquire(), + "http://example.com", + destdir=self.file_unicode, + destfile=self.file_unicode, + ) + + def test_acquire_hashes(self): + hs = apt_pkg.HashString("d41d8cd98f00b204e9800998ecf8427e") + hsl = apt_pkg.HashStringList() + hsl.append(hs) + apt_pkg.AcquireFile( + apt_pkg.Acquire(), + "http://example.com", + hash=hsl, + destdir=self.file_unicode, + destfile=self.file_unicode, + ) + apt_pkg.AcquireFile( + apt_pkg.Acquire(), + "http://example.com", + hash=str(hs), + destdir=self.file_unicode, + destfile=self.file_unicode, + ) + self.assertRaises( + TypeError, + apt_pkg.AcquireFile, + apt_pkg.Acquire(), + "http://example.com", + hash=hs, + destdir=self.file_unicode, + destfile=self.file_unicode, + ) + + def test_ararchive(self): + archive = apt_inst.ArArchive("data/test_debs/data-tar-xz.deb") + + apt_inst.ArArchive(b"data/test_debs/data-tar-xz.deb") + + archive.extract("debian-binary", "data/tmp") + archive.extract(b"debian-binary", b"data/tmp") + archive.extractall("data/tmp") + archive.extractall(b"data/tmp") + self.assertEqual(archive.extractdata("debian-binary"), b"2.0\n") + self.assertEqual(archive.extractdata(b"debian-binary"), b"2.0\n") + self.assertTrue(archive.getmember("debian-binary")) + self.assertTrue(archive.getmember(b"debian-binary")) + self.assertTrue("debian-binary" in archive) + self.assertTrue(b"debian-binary" in archive) + self.assertTrue(archive[b"debian-binary"]) + self.assertTrue(archive["debian-binary"]) + + tar = archive.gettar("control.tar.xz", "xz") + tar = archive.gettar(b"control.tar.xz", "xz") + + tar.extractall(self.dir_unicode) + tar.extractall(self.dir_bytes) + self.assertRaises(LookupError, tar.extractdata, "Do-not-exist") + self.assertRaises(LookupError, tar.extractdata, b"Do-not-exist") + tar.extractdata(b"control") + tar.extractdata("control") + + apt_inst.TarFile(os.path.join(self.dir_unicode, "control.tar.xz")) + apt_inst.TarFile(os.path.join(self.dir_bytes, b"control.tar.xz")) + + def test_configuration(self): + with open(self.file_unicode, "w") as config: + config.write("Hello { World 1; };") + apt_pkg.read_config_file(apt_pkg.config, self.file_bytes) + apt_pkg.read_config_file(apt_pkg.config, self.file_unicode) + apt_pkg.read_config_file_isc(apt_pkg.config, self.file_bytes) + apt_pkg.read_config_file_isc(apt_pkg.config, self.file_unicode) + apt_pkg.read_config_dir(apt_pkg.config, self.dir_unicode) + apt_pkg.read_config_dir(apt_pkg.config, b"/etc/apt/apt.conf.d") + + def test_index_file(self): + apt_pkg.config["dir"] = "data/test_debs" + slist = apt_pkg.SourceList() + slist.read_main_list() + + for meta in slist.list: + for index in meta.index_files: + index.archive_uri(self.file_bytes) + index.archive_uri(self.file_unicode) + + def test_lock(self): + apt_pkg.get_lock(self.file_unicode, True) + apt_pkg.get_lock(self.file_bytes, True) + + with apt_pkg.FileLock(self.file_unicode): + pass + with apt_pkg.FileLock(self.file_bytes): + pass + + def test_policy(self): + apt_pkg.config["dir"] = "data/test_debs" + cache = apt_pkg.Cache(None) + policy = apt_pkg.Policy(cache) + file_unicode = os.path.join(self.dir_unicode, "test.prefs") + file_bytes = os.path.join(self.dir_bytes, b"test.prefs") + + self.assertTrue(policy.read_pinfile(file_unicode)) + self.assertTrue(policy.read_pinfile(file_bytes)) + self.assertTrue(policy.read_pindir(self.dir_unicode)) + self.assertTrue(policy.read_pindir(self.dir_bytes)) + + def test_tag(self): + with open(self.file_bytes, "w") as tag: + tag.write("Key: value\n") + tag1 = apt_pkg.TagFile(self.file_unicode) + tag2 = apt_pkg.TagFile(self.file_bytes) + + self.assertEqual(next(tag1)["Key"], "value") + self.assertEqual(next(tag2)["Key"], "value") + + self.assertRaises(StopIteration, next, tag1) + self.assertRaises(StopIteration, next, tag2) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_pep484.py b/tests/test_pep484.py new file mode 100644 index 0000000..01711dc --- /dev/null +++ b/tests/test_pep484.py @@ -0,0 +1,28 @@ +#!/usr/bin/python3 + +import os +import subprocess +import unittest + + +def hasMyPy(): + try: + subprocess.check_call(["mypy", "--version"]) + except Exception: + return False + return True + + +class PackagePep484TestCase(unittest.TestCase): + @unittest.skipIf(not hasMyPy(), "no mypy available") + def test_pep484_clean(self): + # FIXME: check all of it + top_src_dir = os.path.join(os.path.dirname(__file__), "..", "apt") + os.environ["MYPYPATH"] = os.path.join( + os.path.dirname(__file__), "..", "typehinting" + ) + self.assertEqual(subprocess.call(["mypy", "--strict", top_src_dir]), 0) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_policy.py b/tests/test_policy.py new file mode 100644 index 0000000..ad0032c --- /dev/null +++ b/tests/test_policy.py @@ -0,0 +1,70 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2012 Michael Vogt +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. + +import unittest + +import apt_pkg +import testcommon + +import apt + + +class TestAptPolicy(testcommon.TestCase): + def test_apt_policy_lowlevel(self): + return # TODO: Make tests independent of system state + # get a policy + cache = apt.Cache() + policy = cache._depcache.policy + self.assertNotEqual(policy, None) + # basic tests + pkg = cache["apt"] + self.assertEqual(policy.get_priority(pkg._pkg), 0) + # get priority for all pkgfiles + for ver in pkg.versions: + lowlevel_ver = ver._cand + for pkgfile, i in lowlevel_ver.file_list: + # print pkgfile, i, policy.get_priority(pkgfile) + self.assertTrue(policy.get_priority(pkgfile) >= 1) + self.assertTrue(policy.get_priority(pkgfile) < 1001) + + def test_apt_policy_lowlevel_files(self): + cache = apt_pkg.Cache() + depcache = apt_pkg.DepCache(cache) + policy = cache.policy + dpolicy = depcache.policy + self.assertNotEqual(policy, None) + self.assertNotEqual(dpolicy, None) + + for f in cache.file_list: + policy.get_priority(f) + dpolicy.get_priority(f) + + def test_apt_policy_lowlevel_versions(self): + cache = apt_pkg.Cache() + depcache = apt_pkg.DepCache(cache) + policy = cache.policy + dpolicy = depcache.policy + self.assertNotEqual(policy, None) + self.assertNotEqual(dpolicy, None) + + for pkg in cache.packages: + for ver in pkg.version_list: + policy.get_priority(ver) + dpolicy.get_priority(ver) + + def test_apt_policy_highlevel(self): + return # TODO: Make tests independent of system state + cache = apt.Cache() + pkg = cache["apt"] + self.assertTrue( + pkg.candidate.policy_priority > 1 and pkg.candidate.policy_priority < 1001 + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_progress.py b/tests/test_progress.py new file mode 100644 index 0000000..c823019 --- /dev/null +++ b/tests/test_progress.py @@ -0,0 +1,56 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2010 Michael Vogt +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of apt.progress""" +import os +import unittest + +import apt_pkg +import testcommon + +import apt + + +class TestAcquireProgress(apt.progress.base.AcquireProgress): + def pulse(self, owner): + self.pulsed = True + # there should be a return value here, either (True,False) + # but often this is forgoten (and causes odd error messages) + # so the lib supports it. we test the lack of support value here + + +class TestProgress(testcommon.TestCase): + def setUp(self): + testcommon.TestCase.setUp(self) + basedir = os.path.abspath(os.path.dirname(__file__)) + # setup apt_pkg config + apt_pkg.init() + apt_pkg.config.set("APT::Architecture", "amd64") + apt_pkg.config.set("Dir::Etc", basedir) + # TODO: /dev/null is not a dir, perhaps find something better + apt_pkg.config.set("Dir::Etc::sourceparts", "/dev/null") + # setup lists dir + if not os.path.exists("./tmp/partial"): + os.makedirs("./tmp/partial") + apt_pkg.config.set("Dir::state::lists", "./tmp") + # create artifical line + deb_line = "deb [allow-insecure=yes] file:%s/data/fake-packages/ /\n" % basedir + with open("fetch_sources.list", "w") as fobj: + fobj.write(deb_line) + apt_pkg.config.set("Dir::Etc::sourcelist", "fetch_sources.list") + apt_pkg.config.clear("APT::Update::Post-Invoke") + apt_pkg.config.clear("APT::Update::Post-Invoke-Success") + + def test_acquire_progress(self): + progress = TestAcquireProgress() + cache = apt.Cache() + cache.update(progress) + self.assertTrue(progress.pulsed) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_pyflakes.py b/tests/test_pyflakes.py new file mode 100644 index 0000000..f26433a --- /dev/null +++ b/tests/test_pyflakes.py @@ -0,0 +1,43 @@ +#!/usr/bin/python3 + +import os +import subprocess +import unittest + +import testcommon + + +class TestPyflakesClean(testcommon.TestCase): + EXCLUDES = ["build", "tests/old", ".pybuild"] + TOPLEVEL = os.path.normpath( + os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") + ) + + def is_excluded_path(self, path): + for exclude in self.EXCLUDES: + if path.startswith(os.path.join(self.TOPLEVEL, exclude)): + return True + return False + + def get_py_files(self, toplevel): + files = [] + for path, dirnames, filenames in os.walk(self.TOPLEVEL): + if self.is_excluded_path(path): + continue + for filename in filenames: + if os.path.splitext(filename)[1] == ".py": + files.append(os.path.join(path, filename)) + return files + + def test_pyflakes_clean(self): + cmd = ["pyflakes3"] + self.get_py_files(self.TOPLEVEL) + res = subprocess.call(cmd) + if res != 0: + self.fail("pyflakes failed with: %s" % res) + + +if __name__ == "__main__": + import logging + + logging.basicConfig(level=logging.DEBUG) + unittest.main() diff --git a/tests/test_signed_usable.py b/tests/test_signed_usable.py new file mode 100644 index 0000000..1bd5087 --- /dev/null +++ b/tests/test_signed_usable.py @@ -0,0 +1,403 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2019 Canonical Ltd +# +# SPDX-License-Identifier: GPL-2.0+ + + +import base64 +import os +import shutil +import tempfile +import unittest + +import apt_pkg +import testcommon + +import apt +import apt.progress.base +import apt.progress.text + +# A change in APT to early fail acquire items with weak hashes caused it +# to call progress methods before calling Start(), which confused python-apt's +# locking handling. Hence we need to skip such tests for now, until we can test +# against an apt version with the fix: +# +# https://salsa.debian.org/apt-team/apt/commit/84176f6c +# +RUN_CRASHING_TESTS = False + +# Message APT gives us when hashes are too weak +CACHE_MSG_WEAK_HASH = ( + "Insufficient information available to perform this download securely" +) + + +class TestSignedUsable(testcommon.TestCase): + """Test fetch_binary() and fetch_source() signature checking.""" + + def setUp(self): + testcommon.TestCase.setUp(self) + apt_pkg.config.clear("APT::Update::Post-Invoke") + apt_pkg.config.clear("APT::Update::Post-Invoke-Success") + self.chroot_path = chroot_path = tempfile.mkdtemp() + repo_path = os.path.abspath("./data/test-signed-usable-repo/") + # Inits the dirs for us + apt.cache.Cache(rootdir=chroot_path) + # Change directory + self.cwd = os.getcwd() + os.chdir(chroot_path) + with open( + os.path.join(self.chroot_path, "etc/apt/sources.list"), "w" + ) as sources_list: + sources_list.write("deb copy:%s/signed/ /\n" % repo_path) + sources_list.write("deb copy:%s/unsigned/ /\n" % repo_path) + sources_list.write("deb-src copy:%s/signed/ /\n" % repo_path) + sources_list.write("deb-src copy:%s/unsigned/ /\n" % repo_path) + + with open(os.path.join(repo_path, "key.gpg.base64"), "rb") as pubkey64: + with open( + os.path.join(self.chroot_path, "etc/apt/trusted.gpg"), "wb" + ) as tgt: + tgt.write(base64.b64decode(pubkey64.read())) + + self.cache = apt.cache.Cache(rootdir=chroot_path) + apt_pkg.config["Acquire::AllowInsecureRepositories"] = "true" + self.cache.update() + apt_pkg.config["Acquire::AllowInsecureRepositories"] = "false" + self.cache.open() + + self.progress = apt.progress.text.AcquireProgress + apt.progress.text.AcquireProgress = apt.progress.base.AcquireProgress + + # Disable actual installation of downloaded items + self.cache.install_archives = ( + lambda *a, **b: apt_pkg.PackageManager.RESULT_COMPLETED + ) + + def tearDown(self): + # this resets the rootdir apt_pkg.config to ensure it does not + # "pollute" the later tests + apt.cache.Cache(rootdir="/") + os.chdir(self.cwd) + shutil.rmtree(self.chroot_path) + + apt.progress.text.AcquireProgress = self.progress + + def doInstall(self, name, bargs): + self.cache[name].mark_install() + try: + with apt.progress.base.InstallProgress() as ip: + self.cache.commit(install_progress=ip, **bargs) + finally: + for fname in os.listdir( + os.path.join(self.chroot_path, "var/cache/apt/archives") + ): + if os.path.isfile( + os.path.join(self.chroot_path, "var/cache/apt/archives", fname) + ): + os.unlink( + os.path.join(self.chroot_path, "var/cache/apt/archives", fname) + ) + self.cache[name].mark_keep() + + def doFetchArchives(self, name, bargs): + fetcher = apt_pkg.Acquire() + self.cache[name].mark_install() + try: + self.cache.fetch_archives(fetcher=fetcher, **bargs) + finally: + for fname in os.listdir( + os.path.join(self.chroot_path, "var/cache/apt/archives") + ): + if fname.endswith(".deb"): + os.unlink( + os.path.join(self.chroot_path, "var/cache/apt/archives", fname) + ) + self.cache[name].mark_keep() + + def testDefaultDenyButExplicitAllowUnauthenticated(self): + """Deny by config (default), but pass allow_unauthenticated=True""" + + bargs = dict(allow_unauthenticated=True) + sargs = dict(allow_unauthenticated=True, unpack=False) + + self.doInstall("signed-usable", bargs) + if RUN_CRASHING_TESTS: + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doInstall, + "signed-not-usable", + bargs, + ) + + self.doInstall("unsigned-usable", bargs) + if RUN_CRASHING_TESTS: + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doInstall, + "unsigned-unusable", + bargs, + ) + + self.doFetchArchives("signed-usable", bargs) + self.doFetchArchives("unsigned-usable", bargs) + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doFetchArchives, + "signed-not-usable", + bargs, + ) + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doFetchArchives, + "unsigned-unusable", + bargs, + ) + + self.cache["signed-usable"].candidate.fetch_binary(**bargs) + self.cache["signed-usable"].candidate.fetch_source(**sargs) + self.cache["signed-not-usable"].candidate.fetch_binary(**bargs) + self.cache["signed-not-usable"].candidate.fetch_source(**sargs) + self.cache["unsigned-usable"].candidate.fetch_binary(**bargs) + self.cache["unsigned-usable"].candidate.fetch_source(**sargs) + self.cache["unsigned-unusable"].candidate.fetch_binary(**bargs) + self.cache["unsigned-unusable"].candidate.fetch_source(**sargs) + + def testDefaultAllow(self): + """Allow by config APT::Get::AllowUnauthenticated = True""" + apt_pkg.config["APT::Get::AllowUnauthenticated"] = "true" + + bargs = dict() + sargs = dict(unpack=False) + + self.doInstall("signed-usable", bargs) + if RUN_CRASHING_TESTS: + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doInstall, + "signed-not-usable", + bargs, + ) + self.doInstall("unsigned-usable", bargs) + if RUN_CRASHING_TESTS: + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doInstall, + "unsigned-unusable", + bargs, + ) + + self.doFetchArchives("signed-usable", bargs) + self.doFetchArchives("unsigned-usable", bargs) + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doFetchArchives, + "signed-not-usable", + bargs, + ) + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doFetchArchives, + "unsigned-unusable", + bargs, + ) + + self.cache["signed-usable"].candidate.fetch_binary(**bargs) + self.cache["signed-usable"].candidate.fetch_source(**sargs) + self.cache["signed-not-usable"].candidate.fetch_binary(**bargs) + self.cache["signed-not-usable"].candidate.fetch_source(**sargs) + self.cache["unsigned-usable"].candidate.fetch_binary(**bargs) + self.cache["unsigned-usable"].candidate.fetch_source(**sargs) + self.cache["unsigned-unusable"].candidate.fetch_binary(**bargs) + self.cache["unsigned-unusable"].candidate.fetch_source(**sargs) + + def testDefaultDeny(self): + """Test APT::Get::AllowUnauthenticated = False (default)""" + self.doInstall("signed-usable", {}) + if RUN_CRASHING_TESTS: + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doInstall, + "signed-not-usable", + {}, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doInstall, + "unsigned-usable", + {}, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doInstall, + "unsigned-unusable", + {}, + ) + + self.doFetchArchives("signed-usable", {}) + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doFetchArchives, + "signed-not-usable", + {}, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doFetchArchives, + "unsigned-usable", + {}, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doFetchArchives, + "unsigned-unusable", + {}, + ) + + self.cache["signed-usable"].candidate.fetch_binary() + self.cache["signed-usable"].candidate.fetch_source(unpack=False) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": No trusted hash", + self.cache["signed-not-usable"].candidate.fetch_binary, + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": No trusted hash", + self.cache["signed-not-usable"].candidate.fetch_source, + unpack=False, + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-usable"].candidate.fetch_binary, + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-usable"].candidate.fetch_source, + unpack=False, + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-unusable"].candidate.fetch_binary, + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-unusable"].candidate.fetch_source, + unpack=False, + ) + + def testDefaultAllowButExplicitDeny(self): + """Allow by config, but pass allow_unauthenticated=False""" + apt_pkg.config["APT::Get::AllowUnauthenticated"] = "true" + + bargs = dict(allow_unauthenticated=False) + sargs = dict(allow_unauthenticated=False, unpack=False) + + self.doInstall("signed-usable", bargs) + if RUN_CRASHING_TESTS: + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doInstall, + "signed-not-usable", + bargs, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doInstall, + "unsigned-usable", + bargs, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doInstall, + "unsigned-unusable", + bargs, + ) + + self.doFetchArchives("signed-usable", bargs) + self.assertRaisesRegex( + apt.cache.FetchFailedException, + CACHE_MSG_WEAK_HASH, + self.doFetchArchives, + "signed-not-usable", + bargs, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doFetchArchives, + "unsigned-usable", + bargs, + ) + self.assertRaisesRegex( + apt.cache.UntrustedException, + "Untrusted packages:", + self.doFetchArchives, + "unsigned-unusable", + bargs, + ) + + self.cache["signed-usable"].candidate.fetch_binary(**bargs) + self.cache["signed-usable"].candidate.fetch_source(**sargs) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": No trusted hash", + self.cache["signed-not-usable"].candidate.fetch_binary, + **bargs + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": No trusted hash", + self.cache["signed-not-usable"].candidate.fetch_source, + **sargs + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-usable"].candidate.fetch_binary, + **bargs + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-usable"].candidate.fetch_source, + **sargs + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-unusable"].candidate.fetch_binary, + **bargs + ) + self.assertRaisesRegex( + apt.package.UntrustedError, + ": Source", + self.cache["unsigned-unusable"].candidate.fetch_source, + **sargs + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_size_to_str.py b/tests/test_size_to_str.py new file mode 100644 index 0000000..6320e39 --- /dev/null +++ b/tests/test_size_to_str.py @@ -0,0 +1,104 @@ +#!/usr/bin/python3 + +__author__ = "Barry Warsaw , James Hunt, Michael Vogt" + +import unittest + +import apt_pkg +import testcommon + + +class SizeToStrTestCase(testcommon.TestCase): + """Test apt_pkg.size_to_str""" + + DATA = { + # XXX: note the trailing spaces for some of these entries! + 10**1: "10 ", + 10**2: "100 ", + 10**3: "1000 ", + 10**4: "10.0 k", + 10**5: "100 k", + 10**6: "1000 k", + 10**7: "10.0 M", + 10**8: "100 M", + 10**9: "1000 M", + 10**10: "10.0 G", + 10**11: "100 G", + 10**12: "1000 G", + 10**13: "10.0 T", + 10**14: "100 T", + 10**15: "1000 T", + 10**16: "10.0 P", + 10**17: "100 P", + 10**18: "1000 P", + 10**19: "10.0 E", + 10**20: "100 E", + 10**21: "1000 E", + 10**22: "10.0 Z", + 10**23: "100.0 Z", + 10**24: "1000 Z", + # 10 ** 25: "10.0 Y", + 10**26: "100 Y", + 10**27: "1000 Y", + # That's our limit :) + 10**28: "10000 Y", + 0: "0 ", + 1: "1 ", + 1024: "1024 ", + 10240: "10.2 k", + 102400: "102 k", + 1024000: "1024 k", + 10240000: "10.2 M", + 102400000: "102 M", + 2147483647: "2147 M", + 2147483648: "2147 M", + 1024000000: "1024 M", + 10240000000: "10.2 G", + 9: "9 ", + 99: "99 ", + 999: "999 ", + 9999: "9999 ", + 99999: "100.0 k", + 999999: "1000 k", + 9999999: "10000 k", + 99999999: "100.0 M", + 999999999: "1000 M", + 9999999999: "10000 M", + 99999999999: "100.0 G", + 999999999999: "1000 G", + 9999999999999: "10000 G", + 99999999999999: "100.0 T", + 999999999999999: "1000 T", + 9999999999999999: "10.0 P", + 99999999999999999: "100 P", + 999999999999999999: "1000 P", + 9999999999999999999: "10.0 E", + 99999999999999999999: "100 E", + 999999999999999999999: "1000 E", + 9999999999999999999999: "10.0 Z", + 999999999999999999999999: "1000 Z", + } + + def test_from_data(self): + for k, v in self.DATA.items(): + size = apt_pkg.size_to_str(k) + msg = f"size_to_str({k}) returned '{size}', expected '{v}'" + self.assertEqual(size, v, msg) + + def test_raise_on_unsupported(self): + for v in ["hello", None, {}, [], ()]: + with self.assertRaises(TypeError): + apt_pkg.size_to_str(v) + + +class RegressionTestCase(testcommon.TestCase): + """Regression test for LP: #1030278""" + + def test_no_overflow_error(self): + # LP: #1030278 produces an overflow error in size_to_str() with a big + # value under Python 3. + self.assertEqual(apt_pkg.size_to_str(2147483648000000000000), "2147 E") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_sourcerecords.py b/tests/test_sourcerecords.py new file mode 100644 index 0000000..4b0e6fb --- /dev/null +++ b/tests/test_sourcerecords.py @@ -0,0 +1,129 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2018 Michael Vogt +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of source records in apt_pkg.""" + +import os +import shutil +import sys +import unittest + +from test_all import get_library_dir + +libdir = get_library_dir() +if libdir: + sys.path.insert(0, libdir) + +import apt_pkg +import testcommon + +import apt + + +class TestSourceRecords(testcommon.TestCase): + def setUp(self): + testcommon.TestCase.setUp(self) + + rootdir = "./data/tmp" + if os.path.exists(rootdir): + shutil.rmtree(rootdir) + try: + os.makedirs(os.path.join(rootdir, "etc", "apt")) + except OSError: + pass + + for k in apt_pkg.config.keys(): + apt_pkg.config.clear(k) + + apt_pkg.config["Dir"] = os.path.abspath(rootdir) + apt_pkg.init_config() + + # set a local sources.list that does not need the network + base_sources = os.path.abspath( + os.path.join(rootdir, "etc", "apt", "sources.list") + ) + # main sources.list + sources_list = base_sources + with open(sources_list, "w") as f: + repo = os.path.abspath("./data/test-source-repo") + f.write("deb-src [trusted=yes] copy:%s /\n" % repo) + + self.assertTrue(os.path.exists(sources_list)) + + # update a single sources.list + cache = apt.Cache(rootdir=rootdir) + cache.update(sources_list=sources_list) + + def test_source_records_smoke(self): + src = apt_pkg.SourceRecords() + self.assertTrue(src.step()) + + self.assertEqual(src.maintainer, "Julian Andres Klode ") # noqa + self.assertEqual(src.binaries, ["dh-autoreconf"]) + self.assertEqual(src.package, "dh-autoreconf") + + self.assertEqual(2, len(src.files)) + + # unpacking as a tuple works as before + md5, size, path, type_ = f = src.files[0] + self.assertEqual(md5, None) + self.assertEqual(size, 1578) + self.assertEqual(path, "dh-autoreconf_16.dsc") + self.assertEqual(type_, "dsc") + # access using getters + self.assertTrue(isinstance(f.hashes, apt_pkg.HashStringList)) + self.assertEqual( + str(f.hashes[0]), + "SHA512:4b1a3299f2a8b01b0c75db97fd16cb39919949c74d19ea6cf28e1bbd4891d3515b3e2b90b96a64df665cebf6d95409e704e670909ae91fcfe92409ee1339bffc", + ) # noqa + self.assertEqual(str(f.hashes[1]), "Checksum-FileSize:1578") + self.assertEqual( + str(f.hashes[2]), + "SHA256:1c1b2ab5f1ae5496bd50dbb3c30e9b7d181a06c8d02ee8d7e9c35ed6f2a69b5f", + ) # noqa + self.assertEqual( + str(f.hashes[3]), "SHA1:c9bf7a920013021dad5fbd898dfd5a79c7a150f9" + ) # noqa + self.assertEqual( + str(f.hashes[4]), "MD5Sum:6576a28fe1918ce10bd31543ba545901" + ) # noqa + self.assertEqual(f.size, 1578) + self.assertEqual(f.path, "dh-autoreconf_16.dsc") + self.assertEqual(f.type, "dsc") + + # unpacking as a tuple works as before + md5, size, path, type_ = f = src.files[1] + self.assertEqual(md5, None) + self.assertEqual(size, 7372) + self.assertEqual(path, "dh-autoreconf_16.tar.xz") + self.assertEqual(type_, "tar") + # access using getters + self.assertTrue(isinstance(f.hashes, apt_pkg.HashStringList)) + self.assertEqual( + str(f.hashes[0]), + "SHA512:10448dd179ec12bf4310a9a514110a85f56e51893aa36a97ac3a6f8d7ce99d099e62cfdb78e271e2d94431e8832da0f643de821b6643b80e3f0b0f5d682cf9a9", + ) # noqa + self.assertEqual(str(f.hashes[1]), "Checksum-FileSize:7372") # noqa + self.assertEqual( + str(f.hashes[2]), + "SHA256:5c6a6a362907327bec77a867ff3fd0eceba8015d1b881b48275aff7e4ce0f629", + ) # noqa + self.assertEqual( + str(f.hashes[3]), "SHA1:58459600164398ad6807ddd877a6f814c799c62c" + ) # noqa + self.assertEqual( + str(f.hashes[4]), "MD5Sum:302c8bf43db02412e3f2197fd0f2ee0f" + ) # noqa + self.assertEqual(f.size, 7372) + self.assertEqual(f.path, "dh-autoreconf_16.tar.xz") + self.assertEqual(f.type, "tar") + + self.assertFalse(src.step()) + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_tagfile.py b/tests/test_tagfile.py new file mode 100644 index 0000000..29bf9e8 --- /dev/null +++ b/tests/test_tagfile.py @@ -0,0 +1,186 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2010 Michael Vogt +# Copyright (C) 2012 Canonical Ltd. +# Author: Colin Watson +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. +"""Unit tests for verifying the correctness of apt_pkg.TagFile""" + +import glob +import os +import shutil +import sys +import tempfile +import unittest + +from test_all import get_library_dir + +libdir = get_library_dir() +if libdir: + sys.path.insert(0, libdir) + +import apt_pkg +import testcommon + + +class TestOpenMaybeClearSigned(testcommon.TestCase): + def test_open_trivial(self): + basepath = os.path.dirname(__file__) + fd = apt_pkg.open_maybe_clear_signed_file( + os.path.join(basepath, "./data/test_debs/hello_2.5-1.dsc") + ) + with os.fdopen(fd) as f: + data = f.read() + self.assertTrue(data.startswith("Format: 1.0\n")) + + def test_open_normal(self): + basepath = os.path.dirname(__file__) + fd = apt_pkg.open_maybe_clear_signed_file( + os.path.join(basepath, "./data/misc/foo_Release") + ) + with os.fdopen(fd) as f: + data = f.read() + self.assertTrue(data.startswith("Origin: Ubuntu\n")) + + def xtest_open_does_not_exit(self): + with self.assertRaises(SystemError): + apt_pkg.open_maybe_clear_signed_file("does-not-exists") + + +class TestTagFile(testcommon.TestCase): + """test the apt_pkg.TagFile""" + + def setUp(self): + testcommon.TestCase.setUp(self) + self.temp_dir = tempfile.mkdtemp() + + def tearDown(self): + shutil.rmtree(self.temp_dir) + + def test_tag_file(self): + basepath = os.path.dirname(__file__) + tagfilepath = os.path.join(basepath, "./data/tagfile/*") + # test once for compressed and uncompressed + for testfile in glob.glob(tagfilepath): + # test once using the open() method and once using the path + tagfile = apt_pkg.TagFile(testfile) + for i, stanza in enumerate(tagfile): + pass + self.assertEqual(i, 2) + with open(testfile) as f: + tagfile = apt_pkg.TagFile(f) + for i, stanza in enumerate(tagfile): + pass + self.assertEqual(i, 2) + + def test_errors(self): + # Raises SystemError via lbiapt + self.assertRaises(SystemError, apt_pkg.TagFile, "not-there-no-no") + # Raises Type error + self.assertRaises(TypeError, apt_pkg.TagFile, object()) + + def test_utf8(self): + value = "Tést Persön " + packages = os.path.join(self.temp_dir, "Packages") + with open(packages, "w", encoding="UTF-8") as packages_file: + print("Maintainer: %s" % value, file=packages_file) + print("", file=packages_file) + with open(packages, encoding="UTF-8") as packages_file: + tagfile = apt_pkg.TagFile(packages_file) + tagfile.step() + self.assertEqual(value, tagfile.section["Maintainer"]) + + def test_latin1(self): + value = "Tést Persön " + packages = os.path.join(self.temp_dir, "Packages") + with open(packages, "w", encoding="ISO-8859-1") as packages_file: + print("Maintainer: %s" % value, file=packages_file) + print("", file=packages_file) + with open(packages) as packages_file: + tagfile = apt_pkg.TagFile(packages_file, bytes=True) + tagfile.step() + self.assertEqual(value.encode("ISO-8859-1"), tagfile.section["Maintainer"]) + with open(packages, encoding="ISO-8859-1") as packages_file: + tagfile = apt_pkg.TagFile(packages_file) + tagfile.step() + self.assertEqual(value, tagfile.section["Maintainer"]) + + def test_mixed(self): + value = "Tést Persön " + packages = os.path.join(self.temp_dir, "Packages") + with open(packages, "w", encoding="UTF-8") as packages_file: + print("Maintainer: %s" % value, file=packages_file) + print("", file=packages_file) + with open(packages, "a", encoding="ISO-8859-1") as packages_file: + print("Maintainer: %s" % value, file=packages_file) + print("", file=packages_file) + with open(packages) as packages_file: + tagfile = apt_pkg.TagFile(packages_file, bytes=True) + tagfile.step() + self.assertEqual(value.encode("UTF-8"), tagfile.section["Maintainer"]) + tagfile.step() + self.assertEqual(value.encode("ISO-8859-1"), tagfile.section["Maintainer"]) + + +class TestTagSection(testcommon.TestCase): + """test the apt_pkg.TagFile""" + + def setUp(self): + testcommon.TestCase.setUp(self) + self.temp_dir = tempfile.mkdtemp() + + def tearDown(self): + shutil.rmtree(self.temp_dir) + + def test_write(self): + ts = apt_pkg.TagSection("a: 1\nb: 2\nc: 3\n") + outpath = os.path.join(self.temp_dir, "test") + with open(outpath, "w") as outfile: + ts.write(outfile, [], []) + with open(outpath) as outfile: + self.assertEqual(outfile.read(), "a: 1\nb: 2\nc: 3\n") + + def test_write_order(self): + ts = apt_pkg.TagSection("a: 1\nb: 2\nc: 3\n") + outpath = os.path.join(self.temp_dir, "test") + with open(outpath, "w") as outfile: + ts.write(outfile, ["a", "c", "b"], []) + with open(outpath) as outfile: + self.assertEqual(outfile.read(), "a: 1\nc: 3\nb: 2\n") + + def test_write_invalid_order(self): + ts = apt_pkg.TagSection("a: 1\nb: 2\nc: 3\n") + outpath = os.path.join(self.temp_dir, "test") + with open(outpath, "w") as outfile: + self.assertRaises(TypeError, ts.write, outfile, ["a", 1, "b"], []) + + def test_write_remove(self): + ts = apt_pkg.TagSection("a: 1\nb: 2\nc: 3\n") + outpath = os.path.join(self.temp_dir, "test") + with open(outpath, "w") as outfile: + ts.write(outfile, ["a", "c", "b"], [apt_pkg.TagRemove("a")]) + with open(outpath) as outfile: + self.assertEqual(outfile.read(), "c: 3\nb: 2\n") + + def test_write_rewrite(self): + ts = apt_pkg.TagSection("a: 1\nb: 2\nc: 3\n") + outpath = os.path.join(self.temp_dir, "test") + with open(outpath, "w") as outfile: + ts.write(outfile, ["a", "c", "b"], [apt_pkg.TagRewrite("a", "AA")]) + with open(outpath) as outfile: + self.assertEqual(outfile.read(), "a: AA\nc: 3\nb: 2\n") + + def test_write_rename(self): + ts = apt_pkg.TagSection("a: 1\nb: 2\nc: 3\n") + outpath = os.path.join(self.temp_dir, "test") + with open(outpath, "w") as outfile: + ts.write(outfile, ["a", "z", "b"], [apt_pkg.TagRename("c", "z")]) + with open(outpath) as outfile: + self.assertEqual(outfile.read(), "a: 1\nz: 3\nb: 2\n") + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..6f582bb --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,74 @@ +#!/usr/bin/python3 +# +# Copyright (C) 2010 Michael Vogt +# +# Copying and distribution of this file, with or without modification, +# are permitted in any medium without royalty provided the copyright +# notice and this notice are preserved. + +import datetime +import os +import unittest + +import testcommon + +from apt.utils import get_maintenance_end_date, get_release_date_from_release_file + + +class TestUtils(testcommon.TestCase): + def test_get_release_date_from_release_file(self): + path = os.path.join(os.path.dirname(__file__), "data", "misc", "foo_Release") + t = get_release_date_from_release_file(path) + self.assertEqual( + str(datetime.datetime.fromtimestamp(t, datetime.UTC)), + "2012-04-25 22:49:23+00:00", + ) + + def test_maintenance_time(self): + months_of_support = 18 + # test historic releases, jaunty + release_date = datetime.datetime(2009, 4, 23) + (end_year, end_month) = get_maintenance_end_date( + release_date, months_of_support + ) + self.assertEqual(end_year, 2010) + self.assertEqual(end_month, 10) + # test historic releases, karmic + release_date = datetime.datetime(2009, 10, 29) + (end_year, end_month) = get_maintenance_end_date( + release_date, months_of_support + ) + self.assertEqual(end_year, 2011) + self.assertEqual(end_month, 4) + # test maverick + release_date = datetime.datetime(2010, 10, 10) + (end_year, end_month) = get_maintenance_end_date( + release_date, months_of_support + ) + self.assertEqual(end_year, 2012) + self.assertEqual(end_month, 4) + + # test with modulo zero + release_date = datetime.datetime(2010, 6, 10) + (end_year, end_month) = get_maintenance_end_date( + release_date, months_of_support + ) + self.assertEqual(end_year, 2011) + self.assertEqual(end_month, 12) + + # test dapper + months_of_support = 60 + release_date = datetime.datetime(2008, 4, 24) + (end_year, end_month) = get_maintenance_end_date( + release_date, months_of_support + ) + self.assertEqual(end_year, 2013) + self.assertEqual(end_month, 4) + + # what datetime says + # d = datetime.timedelta(18*30) + # print "end date: ", release_date + d + + +if __name__ == "__main__": + unittest.main() diff --git a/tests/testcommon.py b/tests/testcommon.py new file mode 100644 index 0000000..29917a7 --- /dev/null +++ b/tests/testcommon.py @@ -0,0 +1,30 @@ +"""Common testing stuff""" + +import os +import unittest + +import apt_pkg + + +class TestCase(unittest.TestCase): + """Base class for python-apt unittests""" + + def setUp(self): + self.resetConfig() + + def resetConfig(self): + apt_pkg.config.clear("") + for key in apt_pkg.config.list(): + apt_pkg.config.clear(key) + + # Avoid loading any host config files + os.unsetenv("APT_CONFIG") + apt_pkg.config["Dir::Etc::main"] = "/dev/null" + apt_pkg.config["Dir::Etc::parts"] = "/dev/null" + + apt_pkg.init_config() + apt_pkg.init_system() + + # Restore default values + apt_pkg.config["Dir::Etc::main"] = "apt.conf" + apt_pkg.config["Dir::Etc::parts"] = "apt.conf.d" diff --git a/typehinting/apt_inst.pyi b/typehinting/apt_inst.pyi new file mode 100644 index 0000000..5d6a118 --- /dev/null +++ b/typehinting/apt_inst.pyi @@ -0,0 +1,37 @@ +from typing import * + +class ArArchive: + def extract(self) -> None: ... + +class DebFile: + def __init__(self, file: object) -> None: ... + control: TarFile + data: TarFile + +class TarMember: + def isblk(self) -> bool: ... + def ischr(self) -> bool: ... + def isdev(self) -> bool: ... + def isdir(self) -> bool: ... + def isfifo(self) -> bool: ... + def isfile(self) -> bool: ... + def islnk(self) -> bool: ... + def isreg(self) -> bool: ... + def issym(self) -> bool: ... + + gid: int + linkname: str + major: int + minor: int + mode: int + mtime: int + name: str + size: int + uid: int + +class TarFile: + def extractall(self, rootdir: str = "") -> None: ... + def extractdata(self, member: str) -> bytes: ... + def go( + self, callback: Callable[[TarMember, bytes], None], member: str = "" + ) -> None: ... diff --git a/typehinting/apt_pkg.pyi b/typehinting/apt_pkg.pyi new file mode 100644 index 0000000..756d724 --- /dev/null +++ b/typehinting/apt_pkg.pyi @@ -0,0 +1,390 @@ +from typing import * + +from apt.progress.base import ( + AcquireProgress, + CdromProgress, + InstallProgress, + OpProgress, +) + +class FileLike(Protocol): + def fileno(self) -> int: ... + +class Cdrom: + def add(self, progress: CdromProgress) -> bool: ... + def ident(self, progress: CdromProgress) -> str: ... + +@overload +def gettext(msg: str, domain: str) -> str: ... +@overload +def gettext(msg: str) -> str: ... + +class Configuration(Mapping[str, str]): + def find_file(self, key: str, default: str = "") -> str: ... + def find_dir(self, key: str, default: str = "") -> str: ... + def dump(self) -> str: ... + def find(self, key: str, default: object = None) -> str: ... + def find_b(self, key: str, default: bool = False) -> bool: ... + def set(self, key: str, value: str) -> None: ... + def value_list(self, key: str) -> List[str]: ... + def clear(self, root: object = None) -> None: ... + def __getitem__(self, key: str) -> str: ... + def __iter__(self) -> Iterator[str]: ... + def __len__(self) -> int: ... + +config = Configuration() + +def init() -> None: ... +def init_config() -> None: ... +def init_system() -> None: ... + +# FIXME: this is really a file-like object +def md5sum(o: Any) -> str: ... + +class Dependency: + comp_type: str + comp_type_deb: str + target_pkg: Package + target_ver: str + dep_type_untranslated: str + def all_targets(self) -> List[Version]: ... + +# This is really a SystemError, but we don't want to expose that +class Error(Exception): + pass + +class Package: + name: str + version_list: List[Version] + architecture: str + id: int + current_ver: Version + essential: bool + current_state: int + inst_state: int + selected_state: int + has_versions: bool + has_provides: bool + provides_list: List[Tuple[str, str, Version]] + def get_fullname(self, pretty: bool = False) -> str: ... + +class ProblemResolver: + def __init__(self, cache: DepCache) -> None: ... + def clear(self, pkg: Package) -> None: ... + def protect(self, pkg: Package) -> None: ... + def remove(self, pkg: Package) -> None: ... + def resolve(self, fix_broken: bool = True) -> bool: ... + def resolve_by_keep(self) -> bool: ... + def keep_phased_updates(self) -> bool: ... + +CURSTATE_CONFIG_FILES: int +INSTSTATE_REINSTREQ: int +INSTSTATE_HOLD_REINSTREQ: int + +class Version: + ver_str: str + hash: int + file_list: List[Tuple[PackageFile, int]] + translated_description: Description + installed_size: int + size: int + arch: str + downloadable: bool + is_security_update: bool + id: int + section: str + priority: int + priority_str: str + provides_list: List[Tuple[str, str, str]] + depends_list: Dict[str, List[List[Dependency]]] + parent_pkg: Package + multi_arch: int + MULTI_ARCH_ALL: int + MULTI_ARCH_ALLOWED: int + MULTI_ARCH_ALL_ALLOWED: int + MULTI_ARCH_ALL_FOREIGN: int + MULTI_ARCH_FOREIGN: int + MULTI_ARCH_NO: int + MULTI_ARCH_NONE: int + MULTI_ARCH_SAME: int + +class Description: + file_list: List[Tuple[PackageFile, int]] + +class PackageRecords: + homepage: str + short_desc: str + long_desc: str + source_pkg: str + source_ver: str + record: str + filename: str + md5_hash: str + sha1_hash: str + sha256_hash: str + hashes: HashStringList + def __init__(self, cache: Cache) -> None: ... + def lookup(self, packagefile: Tuple[PackageFile, int], index: int = 0) -> bool: ... + +class PackageFile: + architecture: str + archive: str + codename: str + component: str + filename: str + id: int + index_type: str + label: str + not_automatic: bool + not_source: bool + origin: str + site: str + size: int + version: str + +T = TypeVar("T") + +class TagFile(Iterator[TagSection[AnyStr]]): + @overload + def __new__(cls, file: object) -> TagFile[str]: ... + @overload + def __new__(cls, file: object, bytes: Literal[True]) -> TagFile[bytes]: ... + @overload + def __new__(cls, file: object, bytes: Literal[False]) -> TagFile[str]: ... + def __iter__(self) -> Iterator[TagSection[AnyStr]]: ... + def __enter__(self: T) -> T: ... + def __exit__(self, typ: object, value: object, traceback: object) -> None: ... + def __next__(self) -> TagSection[AnyStr]: ... + +class TagSection(Mapping[str, AnyStr]): + @overload + def __new__(cls, str: Union[str, bytes]) -> TagSection[str]: ... + @overload + def __new__( + cls, str: Union[str, bytes], bytes: Literal[True] + ) -> TagSection[bytes]: ... + @overload + def __new__( + cls, str: Union[str, bytes], bytes: Literal[False] + ) -> TagSection[str]: ... + def __getitem__(self, key: str) -> AnyStr: ... + def get(self, key: str, default: Optional[object] = None) -> AnyStr: ... + def find(self, key: str, default: Optional[object] = None) -> AnyStr: ... + def find_raw(self, key: str, default: Optional[object] = None) -> AnyStr: ... + def __contains__(self, key: object) -> bool: ... + def __len__(self) -> int: ... + def __iter__(self) -> Iterator[str]: ... + +def version_compare(a: str, b: str) -> int: ... +def get_lock(file: str, errors: bool = False) -> int: ... +def pkgsystem_lock() -> None: ... +def pkgsystem_unlock() -> None: ... +def read_config_file(configuration: Configuration, path: str) -> None: ... +def read_config_dir(configuration: Configuration, path: str) -> None: ... +def pkgsystem_lock_inner() -> None: ... +def pkgsystem_unlock_inner() -> None: ... +def pkgsystem_is_locked() -> bool: ... + +SELSTATE_HOLD: int + +class Acquire: + fetch_needed: int + items: List[AcquireItem] + partial_present: int + total_needed: int + workers: List[AcquireWorker] + RESULT_CANCELLED: int + RESULT_FAILED: int + RESULT_CONTINUE: int + def __init__(self, progress: Optional[AcquireProgress] = None) -> None: ... + def run(self) -> int: ... + def shutdown(self) -> None: ... + def get_lock(self, path: str) -> None: ... + +class AcquireWorker: + current_item: AcquireItemDesc + current_size: int + total_size: int + status: str + +class AcquireItem: + active_subprocess: str + complete: bool + desc_uri: str + destfile: str + error_text: str + filesize: int + id: int + is_trusted: bool + local: bool + mode: str + partialsize: int + status: int + + STAT_IDLE: int + STAT_FETCHING: int + STAT_DONE: int + STAT_ERROR: int + STAT_AUTH_ERROR: int + STAT_TRANSIENT_NETWORK_ERROR: int + +class AcquireItemDesc: + description: str + owner: AcquireItem + shortdesc: str + uri: str + +class Hashes: + def __init__(self, object: Union[bytes, FileLike, int]) -> None: ... + hashes: HashStringList + +class HashString: + def __init__(self, type: str, hash: Optional[str] = None) -> None: ... + def verify_file(self, filename: str) -> bool: ... + + hashtype: str + hashvalue: str + usable: bool + +class HashStringList: + def append(self, object: HashString) -> None: ... + def find(self, type: str = "") -> HashString: ... + def verify_file(self, filename: str) -> bool: ... + + file_size: int + usable: bool + +class AcquireFile(AcquireItem): + def __init__( + self, + owner: Acquire, + uri: str, + hash: Optional[Union[HashStringList, str]], + size: int = 0, + descr: str = "", + short_descr: str = "", + destdir: str = "", + destfile: str = "", + ) -> None: ... + +class IndexFile: + def archive_uri(self, path: str) -> str: ... + describe: str + exists: bool + has_packages: bool + is_trusted: bool + label: str + size: int + +class SourceRecordFiles: + hashes: HashStringList + path: str + size: int + type: str + +class SourceRecords: + def lookup(self, name: str) -> bool: ... + def restart(self) -> None: ... + def step(self) -> bool: ... + binaries: List[str] + version: str + files: List[SourceRecordFiles] + index: IndexFile + package: str + section: str + +class ActionGroup: + def __init__(self, depcache: DepCache) -> None: ... + +class MetaIndex: + dist: str + index_files: List[IndexFile] + is_trusted: bool + uri: str + +class SourceList: + list: List[MetaIndex] + def read_main_list(self) -> None: ... + def find_index(self, pf: PackageFile) -> IndexFile: ... + +class PackageManager: + RESULT_FAILED: int + RESULT_COMPLETED: int + RESULT_INCOMPLETE: int + def __init__(self, depcache: DepCache) -> None: ... + def get_archives( + self, fetcher: Acquire, list: SourceList, recs: PackageRecords + ) -> bool: ... + +class Cache: + packages: List[Package] + def __init__(self, progress: Optional[OpProgress] = None) -> None: ... + def __contains__(self, name: Union[str, Tuple[str, str]]) -> Package: ... + def __getitem__(self, name: Union[str, Tuple[str, str]]) -> Package: ... + def __len__(self) -> int: ... + def update( + self, progress: AcquireProgress, sources: SourceList, pulse_interval: int + ) -> int: ... + +class DepCache: + broken_count: int + inst_count: int + del_count: int + keep_count: int + usr_size: int + policy: Policy + def __init__(self, cache: Cache) -> None: ... + def init(self, progress: Optional[OpProgress] = None) -> None: ... + def get_candidate_ver(self, pkg: Package) -> Optional[Version]: ... + def set_candidate_ver(self, pkg: Package, ver: Version) -> bool: ... + def marked_install(self, pkg: Package) -> bool: ... + def marked_upgrade(self, pkg: Package) -> bool: ... + def marked_keep(self, pkg: Package) -> bool: ... + def marked_downgrade(self, pkg: Package) -> bool: ... + def marked_delete(self, pkg: Package) -> bool: ... + def marked_reinstall(self, pkg: Package) -> bool: ... + def is_upgradable(self, pkg: Package) -> bool: ... + def is_garbage(self, pkg: Package) -> bool: ... + def is_auto_installed(self, pkg: Package) -> bool: ... + def is_inst_broken(self, pkg: Package) -> bool: ... + def is_now_broken(self, pkg: Package) -> bool: ... + def mark_keep(self, pkg: Package) -> None: ... + def mark_install( + self, pkg: Package, auto_inst: bool = True, from_user: bool = True + ) -> None: ... + def mark_delete(self, pkg: Package, purge: bool = False) -> None: ... + def mark_auto(self, pkg: Package, auto: bool) -> None: ... + def commit( + self, acquire_progress: AcquireProgress, install_progress: InstallProgress + ) -> None: ... + def upgrade(self, dist_upgrade: bool = True) -> bool: ... + def fix_broken(self) -> bool: ... + def phasing_applied(self, pkg: Package) -> bool: ... + +class Policy: + def get_priority(self, pkg: Union[PackageFile, Version]) -> int: ... + +class SystemLock: + def __enter__(self) -> None: ... + def __exit__(self, typ: object, value: object, traceback: object) -> None: ... + +class FileLock: + def __init__(self, path: str) -> None: ... + def __enter__(self) -> None: ... + def __exit__(self, typ: object, value: object, traceback: object) -> None: ... + +def upstream_version(ver: str) -> str: ... +def get_architectures() -> List[str]: ... +def check_dep(pkg_ver: str, dep_op: str, dep_ver: str) -> bool: ... +def uri_to_filename(uri: str) -> str: ... +def str_to_time(rfc_time: str) -> int: ... +def time_to_str(time: int) -> str: ... +def size_to_str(size: Union[float, int]) -> str: ... +def open_maybe_clear_signed_file(file: str) -> int: ... +def parse_depends( + s: str, strip_multi_arch: bool = True, architecture: str = "" +) -> List[List[Tuple[str, str, str]]]: ... +def parse_src_depends( + s: str, strip_multi_arch: bool = True, architecture: str = "" +) -> List[List[Tuple[str, str, str]]]: ... +def string_to_bool(s: str) -> bool: ... diff --git a/utils/expand_info.py b/utils/expand_info.py new file mode 100755 index 0000000..787b1f0 --- /dev/null +++ b/utils/expand_info.py @@ -0,0 +1,11 @@ +#!/usr/bin/python3 +# +# usage: ./utils/expand_info.py build/data/templates/Debian.info \ +# /usr/share/distro-info/debian.csv + +import sys + +import aptsources.distinfo + +for line in aptsources.distinfo._expand_template(sys.argv[1], sys.argv[2]): + print(line) diff --git a/utils/get_debian_mirrors.py b/utils/get_debian_mirrors.py new file mode 100755 index 0000000..408968c --- /dev/null +++ b/utils/get_debian_mirrors.py @@ -0,0 +1,47 @@ +#!/usr/bin/python3 +# get_debian_mirrors.py - Parse Mirrors.masterlist and create a mirror list. +# +# Copyright (c) 2010-2011 Julian Andres Klode +# +# 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 +import collections +import sys +import urllib.request + +from debian import deb822 + +mirrors = collections.defaultdict(set) +masterlist = urllib.request.urlopen( + "https://mirror-master.debian.org/" "status/Mirrors.masterlist" +) + +for mirror in deb822.Deb822.iter_paragraphs(masterlist): + if "Country" not in mirror: + continue + country = mirror["Country"].split(None, 1)[0] + site = mirror["Site"] + for proto in "http", "ftp": + if "Archive-%s" % proto in mirror: + mirrors[country].add( + "{}://{}{}".format(proto, site, mirror["Archive-%s" % proto]) + ) + +if len(mirrors) == 0: + sys.stderr.write("E: Could not read the mirror list due to " "some unknown issue\n") + sys.exit(1) +for country in sorted(mirrors): + print("#LOC:%s" % country) + print("\n".join(sorted(mirrors[country]))) diff --git a/utils/get_ubuntu_mirrors_from_lp.py b/utils/get_ubuntu_mirrors_from_lp.py new file mode 100755 index 0000000..b3253de --- /dev/null +++ b/utils/get_ubuntu_mirrors_from_lp.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python3 +# +# get_ubuntu_lp_mirrors.py +# +# Download the latest list with available Ubuntu mirrors from Launchpad.net +# and extract the hosts from the raw page +# +# Copyright (c) 2006 Free Software Foundation Europe +# +# Author: Sebastian Heinlein +# +# 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 + +import sys + +import feedparser + +d = feedparser.parse("https://launchpad.net/ubuntu/+archivemirrors-rss") +# d = feedparser.parse(open("+archivemirrors-rss")) + +countries = {} + +for entry in d.entries: + countrycode = entry.mirror_countrycode + if countrycode not in countries: + countries[countrycode] = set() + for link in entry.links: + countries[countrycode].add(link.href) + + +keys = sorted(countries) + +if len(keys) == 0: + sys.stderr.write( + "E: Could not read the mirror list due to some issue" + " -- status code: %s\n" % d.status + ) + sys.exit(1) + +print("mirror://mirrors.ubuntu.com/mirrors.txt") +for country in keys: + print("#LOC:%s" % country) + print("\n".join(sorted(countries[country]))) diff --git a/utils/mirrortest b/utils/mirrortest new file mode 100755 index 0000000..54dcfe7 --- /dev/null +++ b/utils/mirrortest @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +import os +import queue +import random +import re +import socket +import threading +import time +import urllib.error +import urllib.parse +import urllib.request + +import aptsources.distro +import aptsources.sourceslist + +socket.setdefaulttimeout(2) + + +class MirrorTest: + class PingWorker(threading.Thread): + def __init__(self, jobs, results, id): + self.id = id + self.jobs = jobs + self.results = results + self.match_result = re.compile(r"^rtt .* = [\.\d]+/([\.\d]+)/.*") + threading.Thread.__init__(self) + + def run(self): + result = None + while MirrorTest.completed_pings < MirrorTest.todo: + try: + mirror = self.jobs.get(True, 1) + host = mirror.hostname + except: + continue + print( + "Pinging (Worker %s) %s (%s) ..." + % (self.id, host, MirrorTest.completed_pings) + ) + commando = os.popen("ping -q -c 4 -W 2 -i 0.3 %s" % host, "r") + while True: + line = commando.readline() + if not line: + break + result = re.findall(self.match_result, line) + MirrorTest.completed_pings_lock.acquire() + MirrorTest.completed_pings += 1 + if result: + self.results.append([float(result[0]), host, mirror]) + MirrorTest.completed_pings_lock.release() + + def speed_test(self, mirror): + url = f"{mirror.get_repo_urls()[0]}/{self.test_file}" + print("Downloading %s ..." % url) + start = time.time() + try: + urllib.request.urlopen(url).read(51200) + return 50 / (time.time() - start) + except: + return 0 + + def __init__(self, hosts, test_file): + self.test_file = test_file + jobs = queue.Queue() + results = [] + for h in hosts: + jobs.put(h) + self.threads = [] + MirrorTest.completed_pings = 0 + MirrorTest.completed_pings_lock = threading.Lock() + MirrorTest.todo = len(hosts) + + for i in range(10): + t = MirrorTest.PingWorker(jobs, results, i) + self.threads.append(t) + t.start() + + for t in self.threads: + t.join() + + results.sort() + print("\n\nTop ten RTTs:") + for r in results[0:10]: + print(f"{r[1]}: {r[0]}") + print("\n\n") + + results.insert(0, [0, "rand", hosts[random.randint(1, len(hosts))]]) + results.insert(0, [0, "rand", hosts[random.randint(1, len(hosts))]]) + + final = [(self.speed_test(r[2]), r[2]) for r in results[0:12]] + final.sort() + final.reverse() + print("\n\nBest mirrors:") + for f in final: + print(f"{f[1].hostname}: {int(f[0])} KByte/s") + + +if __name__ == "__main__": + distro = aptsources.distro.get_distro() + distro.get_sources(aptsources.sourceslist.SourcesList()) + pipe = os.popen("dpkg --print-architecture") + arch = pipe.read().strip() + test_file = "dists/{}/{}/binary-{}/Packages.gz".format( + distro.source_template.name, + distro.source_template.components[0].name, + arch, + ) + app = MirrorTest(distro.source_template.mirror_set.values(), test_file) -- cgit v1.2.3