今天下载了一个英文pdf书籍,但书签全是大写英文字母,看上去有点别扭,于是想办法用自动化重命名pdf书签,

使书签全部变成首字母大写。

pdf原始书签如下图:

重命名后的pdf书签

自动化动态效果图,两三分钟完成重命名工作。

下面介绍下自动化过程。

uiautomation是我封装的python调用UIAutomation的module,参考 http://www.cnblogs.com/Yinkaisheng/p/3444132.html

运行automation.py -h查看帮助

先使用automation.py -a 获取pdf书签树控件的层次结构,-a参数 是获取光标下的控件,并一直获取父控件直到顶层窗口

在cmd里输入automation.py -a回车后,马上把鼠标移到pdf书签上,3秒后,将打印出控件树

再用此方法获取右键pdf书签右键菜单的控件树层次结构。

最后代码如下:

#!python3
# -*- coding: utf-8 -*-
# rename pdf bookmarks with FoxitReader 6.2.3
import time
import string
import automation TreeDepth = 2 #书签树只有前两层需要重命名
UpperWords = {
'amd': 'AMD',
'arp': 'ARP',
'dhcp': 'DHCP',
'dns': 'DNS',
'ip': 'IP',
'mac': 'MAC',
'unix': 'UNIX',
'pc': 'PC',
'pcs': 'PCs',
'tcp': 'TCP',
'tcp/ip': 'TCP/IP',
'vs': 'VS',
}
LowerWords = ['a', 'an', 'and', 'at', 'for', 'in', 'of', 'the', 'to'] class BookMark():
def __init__(self, name, newName):
self.name = name
self.newName = newName
self.children = [] def main():
window = automation.WindowControl(searchDepth= 1, ClassName= 'classFoxitReader')
window.SetActive()
time.sleep(1)
tree = automation.TreeControl(searchFromControl= window, ClassName= 'SysTreeView32')
childItems = tree.GetChildren()
bookMarks = []
depth = 1
for treeItem in childItems:
if treeItem.ControlType == automation.ControlType.TreeItemControl:
RenameTreeItem(tree, treeItem, bookMarks, depth)
fout = open('rename_pdf_bookmark.txt', 'wt', encoding= 'utf-8')
depth = 1
for bookMark in bookMarks:
DumpBookMark(fout, bookMark, depth)
fout.close() def DumpBookMark(fout, bookMark, depth):
fout.write(' ' * (depth - 1) * 4 + bookMark.newName + '\n')
for child in bookMark.children:
DumpBookMark(fout, child, depth + 1) def RenameTreeItem(tree, treeItem, bookMarks, depth):
treeItem.ScrollIntoView()
if depth > TreeDepth:
return
name = treeItem.Name
newName = Rename(name)
bookMark = BookMark(name, newName)
bookMarks.append(bookMark)
if newName != name:
treeItem.RightClick()
# FoxitReader书签右键菜单(BCGPToolBar,非Windows菜单)弹出后,枚举不到菜单,但从屏幕点上ControlFromPoint能获取到菜单, todo
# 采用特殊处理获取重命名菜单
time.sleep(0.2)
x, y = automation.Win32API.GetCursorPos()
menuItem = automation.ControlFromPoint(x + 2, y + 2)
if menuItem.ControlType == automation.ControlType.MenuItemControl:
#鼠标右下方弹出菜单
while not (menuItem.Name == '重命名(R)' or menuItem.Name == 'Rename'):
y += 20
menuItem = automation.ControlFromPoint(x + 2, y)
else:
#鼠标右上方弹出菜单
menuItem = automation.ControlFromPoint(x + 2, y - 2)
while not (menuItem.Name == '重命名(R)' or menuItem.Name == 'Rename'):
y -= 20
menuItem = automation.ControlFromPoint(x + 2, y)
menuItem.Click()
edit = automation.EditControl(searchFromControl= tree, searchDepth= 1)
edit.SetValue(newName)
automation.Win32API.SendKeys('{Enter}')
print('rename "{0}" to "{1}"'.format(name, newName))
if depth + 1 > TreeDepth:
return
treeItem.Expand()
childItems = treeItem.GetChildren()
if childItems:
treeItem.Expand()
for child in childItems:
RenameTreeItem(tree, child, bookMark.children, depth + 1) def Rename(name):
newName = name.strip().replace('\n', ' ')
#将CHAPTER 10变成10,删除前置CHAPTER
if newName.startswith('CHAPTER '):
newName = newName[len('CHAPTER '):]
newName = newName.title()
words = newName.split()
skipIndex = 1 if words[0][-1].isdigit() else 0
for i in range(len(words)):
lowerWord = words[i].lower()
start_punctuation = ''
end_punctuation = ''
if lowerWord[0] in string.punctuation:
start_punctuation = lowerWord[0]
lowerWord = lowerWord[1:]
if lowerWord[-1] in string.punctuation:
end_punctuation = lowerWord[-1]
lowerWord = lowerWord[:-1]
if lowerWord in UpperWords:
words[i] = start_punctuation + UpperWords[lowerWord] + end_punctuation
continue
if i > skipIndex and lowerWord in LowerWords:
if words[i-1][-1] != ':':
words[i] = lowerWord
newName = ' '.join(words)
return newName if __name__ == '__main__':
main()
input('\npress enter to exit')

  代码可在https://git.oschina.net/yinkaisheng/PythonUIAutomation4Windows 或 GitHub下载

另外此代码是根据FoxReader6.2.3实现的,其它版本不一定支持。

还有运行此程序时要关闭迅雷,在测试时发现如果运行了迅雷,会使pdf右键菜单获取有问题。

使用uiautomation自动化重命名pdf书签,使全大写字母变成首字母大写的更多相关文章

  1. 重命名PDF打印文件名

    Odoo系统默认打印出来的PDF文件都是以当前文档模型对象对应的模板文件名命名的,对用户来说,这样的命名很不友好. 我们希望能够将打印出来的文件名以单号命名,下面是实现这种目的的方法. 在report ...

  2. C# 文件重命名

    记得C# File类中是没有rename这个方法 所以网上很多都用的是move moveTo copy+delete等这些方法 其实以上的方法 虽然可以实现功能 但看起来总觉得很蛋疼 今天百度 突然发 ...

  3. C# rename方法重命名文件

    记得C# File类中是没有rename这个方法 所以网上很多都用的是move moveTo copy+delete等这些方法 其实以上的方法 虽然可以实现功能 但看起来总觉得很蛋疼 今天百度 突然发 ...

  4. linux安装PyCharm,PyCharm常用快捷键及调试模式,pycharm里面对文件夹或者文件进行重命名

    PyCharm常用快捷键及调试模式 2017年10月18日 23:13:43 菜鸟之神 阅读数:5835    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn ...

  5. linux下rename用法--批量重命名

    Linux的rename 命令有两个版本,一个是C语言版本的,一个是Perl语言版本的,早期的Linux发行版基本上使用的是C语言版本的,现在已经很难见到C语言版本的了, 由于历史原因,在Perl语言 ...

  6. linux下rename用法--批量重命名 转

    原文地址:https://www.cnblogs.com/hester/p/5615871.html Linux的rename 命令有两个版本,一个是C语言版本的,一个是Perl语言版本的,早期的Li ...

  7. 苹果系统OSX中Automator批量重命名

    Automator,看字面意思就无比强大,[自动机器].有什么能比自动还让人着魔? 答案是没有✔ 如果你用的是mac,如果你有一堆文件要重新整理命名,如果你还在Goole什么"批量重命名软件 ...

  8. lr文件下载脚本(文件参数化重命名)

    http://wenku.baidu.com/link?url=6oiIadyF9eFS4VshKbfJDnxrBh2IX919ndi0JO8yoqTRNRNIpavFrZJ9LPVb-FBSfbRY ...

  9. bat批处理重命名问题

    因为要重命名的字符串中有文字,导致重命名出来的文件名都变为乱码了,查理一下需要加两句话 1. @Echo Off Chcp 65001>nul SetLocal EnableDelayedExp ...

随机推荐

  1. UVALive - 3027 Corporative Network (并查集)

    这题比较简单,注意路径压缩即可. AC代码 //#define LOCAL #include <stdio.h> #include <algorithm> using name ...

  2. POJ - 1456 贪心+并查集

    做法一:直接贪心,按照利润排序,然后直接尽量给每个活动安排到最晚的时间即可.时间复杂度O(n * d)当d都为10000时,很容易超时.由于这题数据比较水,所有贪心未超时. AC代码 #include ...

  3. SpringBoot SpringSecurity4整合,灵活权限配置,弃用注解方式.

    SpringSecurity 可以使用注解对方法进行细颗粒权限控制,但是很不灵活,必须在编码期间,就已经写死权限 其实关于SpringSecurity,大部分类都不需要重写,需要的只是妥善的配置. 每 ...

  4. Redis进阶实践之十四 Redis-cli命令行工具使用详解第一部分

    一.介绍       redis学了有一段时间了,以前都是看视频,看教程,很少看官方的东西.现在redis的东西要看的都差不多看完了.网上的东西也不多了.剩下来就看看官网的东西吧,一遍翻译,一遍测试. ...

  5. 关于chrom开发者工具priview和respons 数据内容不一致问题

    在昨天晚上2017年8月24日,深夜升级的时候发现你了一个问题:简单的把问题描述一下:新增的一个付款单中的金额为最大值9999999999999999 ,但是保存后返回来的却是100000000000 ...

  6. 关于我上传的activiti自定义流程demo的说明

    最近又收到了一些询问activiti的问题,其中好几个都是向我索要我上传的这个activiti自定义流程demo的数据库设计. 索要的多了,而我早就把这个库给删掉了,所以我便觉得有必要做一个说明: 我 ...

  7. 利用Java API生成50到100之间的随机数

    利用Java API生成50到100之间的随机数 /** * */ package com.you.demo; import java.util.Random; /** * @author Admin ...

  8. MFC中CFileDialog用法

    用CFileDialog选择了一个文件后,使用FILE::fopen打开文件错误,使用 的是相对地址,和王工调试了半天,怎么跟踪也没发现错误,原来如此......... CFileDialog文件选择 ...

  9. C# Split 根据组合字符进行拆分数组用法

    C# Split 根据组合字符进行拆分数组用法,如下代码: string sql = "aaaaaaaaaa{@}bbbbbbbbbb{@}ccccccc#cccccc"; //1 ...

  10. 教你如何制作网页上的友情链接--JavaScript基础

    大部分网站的首页都有友情链接的功能,此功能可通过location对象的href属性来实现…… href属性:设置或检索完整的url字符串 1."友情链接制作"示例代码: <! ...