用于解析Debian包控制头和比较版本字符串的Python库

pydpkg的Python项目详细描述


Build Status

python dpkg

此库可用于:

  1. 从debian格式的包文件中读取和提取控制数据,甚至 在通常缺少dpkg本地实现的平台上

  2. 比较dpkg版本字符串,使用纯python实现 算法描述于 https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Version

  3. 解析debian源代码描述(dsc)文件,检查其内容 并验证它们的源文件是否存在以及校验和是否存在 对的。

这主要用于通常不在 由于 许可限制或缺少本地libapt.so(例如macos)

目前只测试了cpython 2.7和3.5,但至少理论上应该运行 在任何可以安装arpy 图书馆。

安装

使用PyPi安装'pydpkg'包 pip工具:

$ pip install pydpkg
Collecting pydpkg
  Downloading pydpkg-1.1-py2-none-any.whl
  Installing collected packages: pydpkg
  Successfully installed pydpkg-1.1

用法

二进制软件包

读取并提取标题

>>> from pydpkg import Dpkg
>>> dp = Dpkg('/tmp/testdeb_1:0.0.0-test_all.deb')

>>> dp.headers
{'maintainer': u'Climate Corp Engineering <no-reply@climate.com>', 'description': u'testdeb\n a bogus debian package for testing dpkg builds', 'package': u'testdeb', 'section': u'base', 'priority': u'extra', 'installed-size': u'0', 'version': u'1:0.0.0-test', 'architecture': u'all'}

>>> print dp
Package: testdeb
Version: 1:0.0.0-test
Section: base
Priority: extra
Architecture: all
Installed-Size: 0
Maintainer: Climate Corp Engineering <no-reply@climate.com>
Description: testdeb
 a bogus debian package for testing dpkg builds

直接与包裹控制信息交互

>>> dp.message
<email.message.Message instance at 0x10895c6c8>
>>> dp.message.get_content_type()
'text/plain'

获取包文件指纹
>>> dp.fileinfo
{'sha256': '547500652257bac6f6bc83f0667d0d66c8abd1382c776c4de84b89d0f550ab7f', 'sha1': 'a5d28ae2f23e726a797349d7dd5f21baf8aa02b4', 'filesize': 910, 'md5': '149e61536a9fe36374732ec95cf7945d'}
>>> dp.md5
'149e61536a9fe36374732ec95cf7945d'
>>> dp.sha1
'a5d28ae2f23e726a797349d7dd5f21baf8aa02b4'
>>> dp.sha256
'547500652257bac6f6bc83f0667d0d66c8abd1382c776c4de84b89d0f550ab7f'
>>> dp.filesize
910

获取包版本的组件
>>> d.epoch
1
>>> d.upstream_version
u'0.0.0'
>>> d.debian_revision
u'test'

获取任意控制头,大小写无关

>>> d.version
u'1:0.0.0-test'

>>> d.VERSION
u'1:0.0.0-test'

>>> d.description
u'testdeb\n a bogus debian package for testing dpkg builds'

>>> d.get('nosuchheader', 'default')
'default'

将当前版本与候选版本进行比较
>>> dp.compare_version_with('1.0')
1

>>> dp.compare_version_with('1:1.0')
-1

比较两个任意版本字符串

>>> from pydpkg import Dpkg
>>> ver_1 = '0:1.0-test1'
>>> ver_2 = '0:1.0-test2'
>>> Dpkg.compare_versions(ver_1, ver_2)
-1

用作键函数对版本字符串列表进行排序

>>> from pydpkg import Dpkg
>>> sorted(['0:1.0-test1', '1:0.0-test0', '0:1.0-test2'] , key=Dpkg.compare_versions_key)
['0:1.0-test1', '0:1.0-test2', '1:0.0-test0']

使用dpkg-inspect.py脚本检查包

$ dpkg-inspect.py ~/testdeb*deb
Filename: /Home/n/testdeb_1:0.0.0-test_all.deb
Size:     910
MD5:      149e61536a9fe36374732ec95cf7945d
SHA1:     a5d28ae2f23e726a797349d7dd5f21baf8aa02b4
SHA256:   547500652257bac6f6bc83f0667d0d66c8abd1382c776c4de84b89d0f550ab7f
Headers:
  Package: testdeb
  Version: 1:0.0.0-test
  Section: base
  Priority: extra
  Architecture: all
  Installed-Size: 0
  Maintainer: Nathan Mehl <n@climate.com>
  Description: testdeb
   a bogus debian package for testing dpkg builds

源包

读取并提取标题

>>> from pydpkg import Dsc
>>> dsc = Dsc('testdeb_0.0.0.dsc')
>>> dsc.standards_version
'3.9.6'
>>> dsc.format
'3.0 (quilt)'
>>> x.build_depends
'python (>= 2.6.6-3), debhelper (>= 9)'

获取作为字典的全套dsc头文件

>>> dsc.headers
{'Architecture': 'all',
 'Binary': 'testdeb',
 'Build-Depends': 'python (>= 2.6.6-3), debhelper (>= 9)',
 'Checksums-Sha1': ' f250ac0a426b31df24fc2c98050f4fab90e456cd 280 testdeb_0.0.0.orig.tar.gz\n cb3474ff94053018957ebcf1d8a2b45f75dda449 232 testdeb_0.0.0-1.debian.tar.xz\n 80cd7b01014a269d445c63b037b885d6002cf533 841 testdeb_0.0.0.dsc',
 'Checksums-Sha256': ' aa57ba8f29840383f5a96c5c8f166a9e6da7a484151938643ce2618e82bfeea7 280 testdeb_0.0.0.orig.tar.gz\n 1ddb2a7336a99bc1d203f3ddb59f6fa2d298e90cb3e59cccbe0c84e359979858 232 testdeb_0.0.0-1.debian.tar.xz\n b5ad1591349eb48db65e6865be506ad7dbd21931902a71addee5b1db9ae1ac2a 841 testdeb_0.0.0.dsc',
 'Files': ' 142ca7334ed1f70302b4504566e0c233 280 testdeb_0.0.0.orig.tar.gz\n fc80e6e7f1c1a08b78a674aaee6c1548 232 testdeb_0.0.0-1.debian.tar.xz\n 893d13a2ef13f7409c9521e8ab1dbccb 841 testdeb_0.0.0.dsc',
 'Format': '3.0 (quilt)',
 'Homepage': 'https://github.com/TheClimateCorporation',
 'Maintainer': 'Nathan J. Mehl <n@climate.com>',
 'Package-List': 'testdeb',
 'Source': 'testdeb',
 'Standards-Version': '3.9.6',
 'Uploaders': 'Nathan J. Mehl <n@climate.com>',
 'Version': '0.0.0-1'}

直接与dsc消息交互

>>> dsc.message
<email.message.Message instance at 0x106fedea8>
>>> dsc.message.get_content_type()
'text/plain'
>>> dsc.message.get('uploaders')
'Nathan J. Mehl <n@climate.com>'

将dsc消息呈现为字符串

>>> print(dsc)
Format: 3.0 (quilt)
Source: testdeb
Binary: testdeb
Architecture: all
Version: 0.0.0-1
Maintainer: Nathan J. Mehl <n@climate.com>
Uploaders: Nathan J. Mehl <n@climate.com>
Homepage: https://github.com/TheClimateCorporation
Standards-Version: 3.9.6
Build-Depends: python (>= 2.6.6-3), debhelper (>= 9)
Package-List: testdeb
Checksums-Sha1:
 f250ac0a426b31df24fc2c98050f4fab90e456cd 280 testdeb_0.0.0.orig.tar.gz
 cb3474ff94053018957ebcf1d8a2b45f75dda449 232 testdeb_0.0.0-1.debian.tar.xz
 80cd7b01014a269d445c63b037b885d6002cf533 841 testdeb_0.0.0.dsc
Checksums-Sha256:
 aa57ba8f29840383f5a96c5c8f166a9e6da7a484151938643ce2618e82bfeea7 280 testdeb_0.0.0.orig.tar.gz
 1ddb2a7336a99bc1d203f3ddb59f6fa2d298e90cb3e59cccbe0c84e359979858 232 testdeb_0.0.0-1.debian.tar.xz
 b5ad1591349eb48db65e6865be506ad7dbd21931902a71addee5b1db9ae1ac2a 841 testdeb_0.0.0.dsc
Files:
 142ca7334ed1f70302b4504566e0c233 280 testdeb_0.0.0.orig.tar.gz
 fc80e6e7f1c1a08b78a674aaee6c1548 232 testdeb_0.0.0-1.debian.tar.xz
 893d13a2ef13f7409c9521e8ab1dbccb 841 testdeb_0.0.0.dsc

列出dsc中的包源文件
>>> dsc.source_files
['/tmp/testdeb_0.0.0.orig.tar.gz',
 '/tmp/testdeb_0.0.0-1.debian.tar.xz',
 '/tmp/testdeb_0.0.0.dsc' ]

验证包源文件是否存在

>>> dsc.missing_files
[]
>>> dsc.all_files_present
True
>>> dsc.validate()
>>>

>>> bad = Dsc('testdeb_1.1.1-bad.dsc')
>>> bad.missing_files
['/tmp/testdeb_1.1.1.orig.tar.gz', '/tmp/testdeb_1.1.1-1.debian.tar.xz']
>>> bad.all_files_present
False
>>> bad.validate()
pydpkg.DscMissingFileError: ['/tmp/testdeb_1.1.1.orig.tar.gz', '/tmp/testdeb_1.1.1-1.debian.tar.xz']

从dsc检查源文件校验和

>>> pp(dsc.checksums)
{'md5': {'/tmp/testdeb_0.0.0-1.debian.tar.xz': 'fc80e6e7f1c1a08b78a674aaee6c1548',
         '/tmp/testdeb_0.0.0.dsc': '893d13a2ef13f7409c9521e8ab1dbccb',
         '/tmp/testdeb_0.0.0.orig.tar.gz': '142ca7334ed1f70302b4504566e0c233'},
 'sha1': {'/tmp/testdeb_0.0.0-1.debian.tar.xz': 'cb3474ff94053018957ebcf1d8a2b45f75dda449',
          '/tmp/testdeb_0.0.0.dsc': '80cd7b01014a269d445c63b037b885d6002cf533',
          '/tmp/testdeb_0.0.0.orig.tar.gz': 'f250ac0a426b31df24fc2c98050f4fab90e456cd'},
 'sha256': {'/tmp/testdeb_0.0.0-1.debian.tar.xz': '1ddb2a7336a99bc1d203f3ddb59f6fa2d298e90cb3e59cccbe0c84e359979858',
            '/tmp/testdeb_0.0.0.dsc': 'b5ad1591349eb48db65e6865be506ad7dbd21931902a71addee5b1db9ae1ac2a',
            '/tmp/testdeb_0.0.0.orig.tar.gz': 'aa57ba8f29840383f5a96c5c8f166a9e6da7a484151938643ce2618e82bfeea7'}}

验证所有源文件校验和是否正确

>>> dsc.corrected_checksums
{}
>>> dsc.all_checksums_correct
True
>>> dsc.validate()
>>>

>>> bad = Dsc('testdeb_0.0.0-badchecksums.dsc')
>>> bad.corrected_checksums
{'sha256': defaultdict(None, {'/tmp/testdeb_0.0.0-1.debian.tar.xz': '1ddb2a7336a99bc1d203f3ddb59f6fa2d298e90cb3e59cccbe0c84e359979858', '/tmp/testdeb_0.0.0.orig.tar.gz': 'aa57ba8f29840383f5a96c5c8f166a9e6da7a484151938643ce2618e82bfeea7'}), 'sha1': defaultdict(None, {'/tmp/testdeb_0.0.0-1.debian.tar.xz': 'cb3474ff94053018957ebcf1d8a2b45f75dda449', '/tmp/testdeb_0.0.0.orig.tar.gz': 'f250ac0a426b31df24fc2c98050f4fab90e456cd'})}
>>> bad.all_checksums_correct
False
>>> bad.validate()
pydpkg.DscBadChecksumsError: {'sha256': defaultdict(None, {'/tmp/testdeb_0.0.0-1.debian.tar.xz': '1ddb2a7336a99bc1d203f3ddb59f6fa2d298e90cb3e59cccbe0c84e359979858', '/tmp/testdeb_0.0.0.orig.tar.gz': 'aa57ba8f29840383f5a96c5c8f166a9e6da7a484151938643ce2618e82bfeea7'}), 'sha1': defaultdict(None, {'/tmp/testdeb_0.0.0-1.debian.tar.xz': 'cb3474ff94053018957ebcf1d8a2b45f75dda449', '/tmp/testdeb_0.0.0.orig.tar.gz': 'f250ac0a426b31df24fc2c98050f4fab90e456cd'})}

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
检查java中两个链表之间的子集   java仅在findViewById()下显示一个ImageButton   在Java Graphics2D中,文本如何在矩形上居中对齐?   java需要一个用于电子表格计算器的正则表达式   ^java中的运算符   java通过一些属性配置文件根据环境动态更改wsdl端点URL   java Ebean/Play框架关系未更新   集合如何将POJO列表转换为Java流中的映射<String,List>?   java为什么JFrame不显示整个图像?   java如何将调用静态导入的泛型方法的结果传递给另一个方法?   迭代器或foreach中的java延迟   需要java socket logback日志接收器   在Java中初始化Map的静态数组   雅加达邮件Java MimeMail:解码后获得额外字符   java为什么这个xmldom解析器不能正确解析rtept、name和cmt标记?   java如何刷新Log4J2中的异步记录器(带中断器)   java使用构建插件pom生成的jar。xml作为同一pom中的依赖项   java基于位置的序列ADT如何在O(1)时间内插入元素?   java ORM实体与DDD实体   Java对象分配