文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

怎么用Python扩展和延伸Nautilus

2023-06-16 20:49

关注

这篇文章主要介绍了怎么用Python扩展和延伸Nautilus,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。

Nautilus 脚本

扩展 Nautilus 的第一个方法是通过在 /home 中发现的名为 .gnome2/nautilus-scripts 的特定目录。当在 Scripts  菜单下的文件或者文件夹上点击鼠标右键时,该目录下所有可执行文件将会出现。还可以选择多个文件或者文件夹,并采用相同的右击方法,将文件清单传递给脚本。

当调用脚本时,Nautilus 支持多个包含当前目录以及所选文件等内容的环境变量。表 1 展示了这些环境变量。

表 1. Nautilus 环境变量

环境变量描述
NAUTILUS_SCRIPT_SELECTED_FILE_PATHS所选文件的新行分割路径(仅针对本地)
NAUTILUS_SCRIPT_SELECTED_URIS所选文件的新行分割 URIs
NAUTILUS_SCRIPT_CURRENT_URI当前位置
NAUTILUS_SCRIPT_WINDOW_GEOMETRY当前窗口的位置和大小

在 Python 中,通过对 os.environ.get 函数的一个调用来获取这些变量的值,具体如下:

selected = os.environ.get('NAUTILUS_SCRIPT_SELECTED_FILE_PATHS,'')

此调用返回一个字符串,其包含到达由换行符分隔的全部所选文件。Python 利用下列代码,简化了将这一字符串返回到可迭代列表中的操作:

targets = selected.splitlines()

此时,也许应该停下来探讨一下用户交互。当控制从 Nautilus  传送到脚本后,在该点上确实不存在对脚本的限制。根据脚本作用的不同,甚至不需要任何用户反馈,除了一些类型的完成或错误消息,这样通过一些简单的消息框就可处理好。由于在编写  Nautilus 时采用了 gtk windowing 工具包,所以尽管这不是必须的,但是采用相同的做法很合乎逻辑。您可以很方便地使用 TkInter 或者  wxPython。

鉴于本文的目的,您将采用  gtk。生成一个用于通信完成状态的简单消息框,仅需几行代码,出于方便阅读的目的,如果想创建简单的函数来生成消息,这个代码将最为合适。总共需要 4  行代码:

def alert(msg):dialog = gtk.MessageDialog()dialog.set_markup(msg)dialog.run()

示例:创建简单脚本来返回所选文件的数量

第一个示例程序将多个程序段合并成一个简单脚本,来返回当前所选文件的数量。这一脚本可用于文件或者目录。可利用另一个 Python  库函数,os.walk,递归地构建每个目录中文件的清单。总共有 38 行代码,如清单 1 所示,这就是这一小工具所需的全部内容,其中还包括了空行。

清单 1. 用于 Filecount 脚本的 代码 Python

#!/usr/bin/env pythonimport pygtkpygtk.require('2.0')import gtkimport osdef alert(msg):"""Show a dialog with a simple message."""dialog = gtk.MessageDialog()dialog.set_markup(msg)dialog.run()def main():selected = os.environ.get('NAUTILUS_SCRIPT_SELECTED_URIS', '')curdir = os.environ.get('NAUTILUS_SCRIPT_CURRENT_URI', os.curdir)if selected:targets = selected.splitlines()else:targets = [curdir]files = []directories = []for target in targets:if target.startswith('file:///'):target = target[7:]for dirname, dirnames, filenames in os.walk(target):for dirname in dirnames:directories.append(dirname)for filename in filenames:files.append(filename)alert('%s directories and %s files' %(len(directories),len(files)))if __name__ == "__main__":main()

图 1 展示了当在文件上右击鼠标或者选择一组文件时所看到的内容。Scripts 菜单选项展示 .gnome2/nautilus-scripts  中所有的可执行文件,并给出了打开文件夹的选项。选择一个文件来执行该脚本。

怎么用Python扩展和延伸Nautilus

图 1.在 Nautilus 中选择文件

图 2 展示了 Filecount.py 脚本的运行结果。

怎么用Python扩展和延伸Nautilus

图 2. Filecount.py 输出

在调试 Nautilus 脚本时,有几件事需要注意。第一件事是关闭 Nautilus  的所有实例,来使它完全重新加载,并找到新脚本或者扩展。可采用如下命令:

nautilus -q

下一个常用命令可实现不必打开首选或者配置数据,而直接运行  Nautilus。这在解决脚本或者扩展在无意间造成破坏之类的问题时,会节省很多步骤。命令如下:

nautilus -no-desktop

确保 filecount 工具可被 Nautilus 访问所剩的最后一步是将其复制到 ~/.gnome2/nautilus-scripts  目录,并改变文件代码来允许执行,相关命令是:

chmod +x Filecount.py

示例:创建文件 cleanup 工具

第二个例子是,创建文件 cleanup 工具,来查找任何可能由 Vim 或者 EMACS 之类的编辑器临时生成的文件。仅通过简单地修改 check  函数,就可利用相同的概念来清除任何特定文件的目录。这一代码属于静默操作,这意味着它执行后不向用户提供任何反馈。

该脚本的主函数看上去基本与前面具的示例相同,除了几个微不足道的异常。此代码会利用递归概念多次调用主函数,直至处理完最后一个目录为止。您可以采用  os.walk 函数,而不必采用递归来完成相同的任务。文件检查发生在 check  函数中,仅简单地检查以波浪号(~)或者井号(#)结束的文件,以井号后开始或扩展名 .pyc 结束的文件。该示例展示了 Python 标准库 os  模块所提供的数量众多的函数。它还提供了独立于操作系统方式来操作路径名和目录,以及执行文件操作的示例。清单 2 展示了该脚本的代码。

清单 2. 用于 cleanup 脚本的 Python 代码

#!/usr/bin/env pythonimport pygtkpygtk.require('2.0')import gtkimport osdef check(path):"""Returns true to indicate a file should be removed."""if path.endswith('~'):return Trueif path.startswith('#') and basename.endswith('#'):return Trueif path.endswith('.pyc'):return Truereturn Falsedef walk(dirname=None):selected = os.environ.get('NAUTILUS_SCRIPT_SELECTED_FILE_PATHS', '')curdir = os.environ.get('NAUTILUS_SCRIPT_CURRENT_URI', os.curdir)if dirname is not None:targets = [dirname]elif selected:targets = selected.splitlines()else:targets = [curdir]for target in targets:if target.startswith('file:///'):target = target[7:]if not os.path.isdir(target): continuefor dirname, dirnames, files in os.walk(target):for dir in dirnames:dir = os.path.join(dirname, dir)walk(dir)for file in files:file = os.path.join(dirname, file)if check(file):os.remove(file)if __name__ == '__main__':walk()

Nautilus 扩展

增强 Nautilus 的第二个方法是通过创建扩展。此方法比第一个复杂,但有很多优势。Nautilus  扩展可被内嵌到文件展示窗口中,那么就可以编写利用以前没有的信息来填充列的扩展。首先要做的就是利用如下命令安装 python-nautilus 扩展:

sudo apt-get install python-nautilus

此命令下载并安装所需的文件,包括文档和示例。可在目录 /usr/share/doc/python-nautilus/examples  中到找到示例代码。安装完成后,就可以访问一组 Nautilus 类和提供程序来再次对其进行编码。表 2 展示了该清单。

表 2. Nautilus 类与供应商

类或者供应商描述
nautilus.Column引用 Nautilus column 对象
nautilus.FileInfo引用 Nautilus fileinfo 对象
nautilus.Menu引用 Nautilus menu 对象
nautilus.MenuItem引用 Nautilus menuitem 对象
nautilus.PropertyPage引用 Nautilus propertypage 对象
nautilus.ColumnProvider允许在 Nautilus 列中展示输出
nautilus.InfoProvider提供关于文件的信息
nautilus.LocationWidgetProvider展示位置
nautilus.MenuProvider为右击菜单增加新功能
nautilus.PropertyPageProvider为属性页面增加信息

gnome.org 站点上提供的示例展示了 MenuProvider(background-image.py 和  open-terminal.py)、ColumnProvider 以及 InfoProvider(block-size-column.py)、和  PropertyPageProvider(md5sum-property-page.py)的使用。ColumnProvider 采用 13 行 Python  可执行代码来向 Nautilus 引入新的列。一旦该代码被放置到合适的目录中(~/.nautilus/python-extensions)并且 Nautilus  已重启,在单击 View > Visible Columns 时将会看到新的选项。当将查看类型设置为 List 时,才会出现 Visible  Columns 选项。通过选择展示以下 Python 库调用结果的复选框,来启用 Block size 列:

str(os.stat(filename).st_blksize))

任何 Python 扩展的基本模式都是对现有 Nautilus 提供程序基本类进行子类划分,然后执行一系列指令,并最终返回合适的 Nautilus  对象。在 block-size-column.py 例子中,返回的对象是 nautilus.Column。必须向 Nautilus 传递 4 个参数,包括  name、attribute、label、以及 description。本例子的 Python 代码是:

return nautilus.Column("NautilusPython::block_size_column","block_size","Block size","Get the block size")

编写新扩展的代码涉及继承来自特定基本类的信息。 在 block-size-column.py 的例子中,nautilus.ColumnProvider 与  nautilus.InfoProvider 在类定义中有举例,因此新类要从这两处继承。接下来需要覆盖来自基类或者类的任何方法来填充列。在  block-size-column.py 例子中,可通过覆盖 get_columns 和 update_file_info 方法来完成。

向 Nautilus 扩展传递信息的方法与脚本示例不同。Nautilus 实际上是启动新的流程来执行脚本,并设置多个环境变量来传递信息。在与  Nautilus 相同的流程中执行的扩展,能够访问对象、方法、和属性。通过 nautilus.FileInfo 传递的文件信息,包括  file_type、location、name、uri、以及 mime_type。想要向 FileInfo 对象增加信息,必须调用  add_string_attribute 方法。下面的例子是采用这一方法,来向 FileInfo 对象增加新的属性。

示例:列出了文件中的行数

第一个例子使用 PropertyPageProvider 方法在文件(或多个文件)上单击右键显示行数和参数,然后单击  Properties。这一扩展背后的基本思想是计算文件中的行数和参数个数,并在文件属性页的新选项卡中报告结果。扩展可以直接访问了 Nautilus  数据结构,包括 file 对象。惟一要做的是利用 urllib.unquote 库函数来打开名字,操作如下:

filename = urllib.unquote(file.get_uri()[7:]

Python 中的一些行完成了对行及参数计数的主要工作。对于本例来说,创建 count  函数来将整个文件读取到一个大字符串中,然后计算参数数量及新添参数数量。因为属性页面可被显示为很多选中的文件及目录,所以必须预先计算多个文件。此时,惟一要做的就是将结果添加到属性页上的新页中。本例创建了示例  gtk.Hbox,然后利用获取的信息来填充大量标签,如清单 3 所示。

清单 3. Linecountextension.py 文件

import nautilusimport urllibimport gtkimport ostypes = ['.py','.js','.html','.css','.txt','.rst','.cgi']exceptions = ('MochiKit.js',)class LineCountPropertyPage(nautilus.PropertyPageProvider):def __init__(self):passdef count(self, filename):s = open(filename).read()return s.count('\n'), len(s)def get_property_pages(self, files):if not len(files):returnlines = 0chars = 0for file in files:if not file.is_directory():result = self.count(urllib.unquote(file.get_uri()[7:]))lines += result[0]chars += result[1]self.property_label = gtk.Label('Linecount')self.property_label.show()self.hbox = gtk.HBox(0, False)self.hbox.show()label = gtk.Label('Lines:')label.show()self.hbox.pack_start(label)self.value_label = gtk.Label()self.hbox.pack_start(self.value_label)self.value_label.set_text(str(lines))self.value_label.show()self.chars_label = gtk.Label('Characters:')self.chars_label.show()self.hbox.pack_start(self.chars_label)self.chars_value = gtk.Label()self.hbox.pack_start(self.chars_value)self.chars_value.set_text(str(chars))self.chars_value.show()return nautilus.PropertyPage("NautilusPython::linecount",self.property_label, self.hbox),

图 3 展示了在文件上单击右键并单击 Linecount  选项卡的结果。此时,需要注意,这一特性可用于文件或者任何一组选定的文件和目录。所报告的数字将代表所有文件中的所有行。

怎么用Python扩展和延伸Nautilus

图 3. 单击 Linecount 选项卡来查看文件的行数

最后,修改扩展函数来填充一列而不是整个属性页。因而代码的修改相当少,尽管需要同时从 nautilus.ColumnProvider 和  nautilus.InfoProvider 继承。还必须执行 get_columns 和 update_file_info。方法 get_columns  仅返回由方法 count 获取的信息。

方法 count 为列提供程序扩展采用不同的技术。Python 的 readlines 例程用于将一个文件的所有行读取到一列字符串中。计算行的总数就是在  len(s)  语句中返回的清单元素的数量。在两个例子中都要进行文件类型检查:这是要确保仅对包含需要计数行的文本文件进行计数。可利用如下行来创建一列可接受的文件扩展:

types = ['.py','.js','.html','.css','.txt','.rst','.cgi']

第二个清单包含了不会被计数的异常,对于本例来说,包含具有如下行的文件:

exceptions = ['MochiKit.js']

这两个清单用于包括或者排除具有如下两行代码的文件:

if ext not in types or basename in exceptions:return 0

整个扩展需要 26 行可执行代码。您可能想要修改扩展,并输入清单来包含或者排除感兴趣的文件,清单 4 展示了完整的扩展。

清单 4. 用于 Linecountcolumn 扩展的 Python 代码

import nautilusimport urllibimport ostypes = ['.py','.js','.html','.css','.txt','.rst','.cgi']exceptions = ['MochiKit.js']class LineCountExtension(nautilus.ColumnProvider, nautilus.InfoProvider):def __init__(self):passdef count(self, filename):ext = os.path.splitext(filename)[1]basename = os.path.basename(filename)if ext not in types or basename in exceptions:return 0s = open(filename).readlines()return len(s)def get_columns(self):return nautilus.Column("NautilusPython::linecount","linecount","Line Count","The number of lines of code"),def update_file_info(self, file):if file.is_directory():lines = 'n/a'else:lines = self.count(urllib.unquote(file.get_uri()[7:]))file.add_string_attribute('linecount', str(lines))

图 4 显示了启用 Line Count 列的 Nautilus  窗口。每个单独的文件显示全部行数。您需要利用该方法进行一次计算就可以知道您总共需要多少个文件。

怎么用Python扩展和延伸Nautilus

图 4. Nautilus 窗口中的 Line Count 列

感谢你能够认真阅读完这篇文章,希望小编分享的“怎么用Python扩展和延伸Nautilus”这篇文章对大家有帮助,同时也希望大家多多支持编程网,关注编程网行业资讯频道,更多相关知识等着你来学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯