0%

工作中经常需要查询腾讯云API文档,为了提高检索效率,决定制作成dash-docset,毕竟dash下进行文档搜索还是高效的。

这里总结下制作流程

效果

https://static.1991421.cn/2022/2022-06-19-230436.gif

原理

  1. 爬虫爬取腾讯云API文档,保存为HTML网页
    • dash下无论是官方提供的docset还是社区贡献的,本质都是爬取的文档网页或者直接使用的文档MD文件,MD文件的好处是结构简单,更易于加工处理
    • 腾讯云API文档没有开源MD文件等,因此这里只能选择爬取网页
  2. 递归解析所有网页,提取interface/function等信息,网页名称及层级可以逆向获取在线URL路径
    • 网页结构只要规范,解析问题并不大
  3. 提取的信息按照dash官方提供的数据结构进行存取,最终打包为docset即可

确定了基本的方向就可以上手制作了。

制作

  1. 关于爬取网页,目前采用wget命令,该命令支持递归抓取,

    • 注意curl不支持递归,因此不考虑
  2. 按照dash要求创建文档结构及sqllite数据表

  3. 利用Node.JS解析HTML文件获取元数据信息,逐行插入DB中

    • 一开始考虑解析完所有文档再批量插入,但文档过多容易造成内存溢出,因此这里采取每个文档解析完,执行一次批量插入数据
    • dash支持浏览本地文档或者在线文档,本地文档的好处是排版完全可控,相反在线文档的只托管了网址,但排版就不可控了。这里为了简单,因此只托管了网址,无论是首页还是各个API网页均直接访问的在线网址。
  4. 执行tar打包命令

  5. 编写feed.xml文件,从而方便他人订阅

    • dash中同步并不会同步加载的本地docset,因此如果是多设备共享docset,这里需要制作成feed,其它设备订阅即可,当然也可以按照官方推荐的提交到官方仓库中。

整体制作脚本及docset都托管在了这里

写在最后

  1. 该方案主要解决了关键词快速检索定位文档URL,最终还是dash内的网页浏览。如上所说也可以处理做到本地文档浏览,但这样就意味着文档可能会有出入并非最新的,同时排版/样式需要特殊处理解决,URL还是本地文档需要看需求解决
  2. 类似API方面的文档检索如果没有现成的docset,均可以采用此方案来解决。

相关文档

最近在做webshell,除了sz/rz命令方式实现上传下载之外,需要GUI方式实现基本的文件操作,比如拉取文件列表,上传下载。

调研后决定使用基于sftp/ssh实现的ssh2-sftp-client

这里总结下使用中遇到的问题

服务禁用/开启设定

每个Linux机器默认都有SFTP服务,毕竟底层是SSH协议,算是标配,但用户可以通过在服务端设置来选择开启和关闭sftp服务的。

因此在实际开发中要考虑到服务不可用场景下的处理

1
2
3
4
5
6
7
8
9
10
11
# vi /etc/ssh/sshd_config

# override default of no subsystems
Subsystem sftp /usr/libexec/openssh/sftp-server


After
# override default of no subsystems
# Subsystem sftp /usr/libexec/openssh/sftp-server

service sshd restart

如果服务没有正常开启,则异常错误码是ERR_GENERIC_CLIENT

https://static.1991421.cn/2022/2022-06-12-230743.jpeg

list

如果是想拉取文件列表,使用的是list方法,有几个问题需要注意

  1. 不支持~

    remotePath路径必须是相对或者绝对路径,不可以是路径别名,比如

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    async function main() {
    try {
    await sftp.connect(config);
    let fileList = await sftp.list(remotePath);
    console.log(fileList);
    await sftp.end();
    } catch (e) {
    console.error(e);
    }
    }
  2. 文件type

    返回结果中有type字段,表示文件类型,其中

    • d是文件夹
    • -是文件
    • l是软链接

针对链接类型文件,想知道具体是文件还是文件夹,只能再去单独查询判断,比如使用stat方法,返回值中isDirectory,isFile可以明确具体类别

  1. size单位为字节

    这点与一般shell命令显示单位一致

  2. rights权限

    通过list接口可以拿到文件所属user/group,同时文件针对所属user/group/other权限,rights与longname信息等价,只是rights将权限信息结构化显示。owner字段表示归属userID,group表示归属groupID。通过信息还是无法直接判断当前用户对该文件是否有读写权限,为了判断需要SSH单独执行id username命令来获取当前用户userID和groupID

    举个例子如下,注意SSH2Client并不是sftpClient,这个需要使用ssh2下的client单独连接,sftp包不支持

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    const {Client: SSH2Client} = require('ssh2');

    const ssh2Client = new SSH2Client();

    await new Promise(resolve => ssh2Client.connect(config).on('ready', () => {
    return ssh2Client.exec(`id ${config.username}`, (err, stream) => {
    stream.on('data', (buf) => {
    const idRes = buf.toString();
    console.log(idRes); // uid=0(root) gid=0(root) groups=0(root)
    const rights = idRes.match(/\d+/g);
    console.log({
    uid: +rights[0],
    gid: +rights[1],
    });
    return resolve(idRes);
    });
    })
    }));

    当拿到权限信息后,结合list接口返回的信息即可判断。

    1
    2
    3
    4
    5
    const rights = idRes.match(/\d+/g);
    console.log({
    uid: +rights[0],
    gid: +rights[1],
    });

返回数据结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
"type": "-", // 文件类型
"name": "admin1.pem", // 文件名
"size": 418, // 文件体积,字节数
"modifyTime": 1651807713000,
"accessTime": 1651807715000,
"rights": {
"user": "rw",
"group": "r",
"other": "r"
},
"owner": 0,
"group": 0
}

put/fastPut

  1. 上传文件时可以使用这两个方法,区别主要在于是否支持流。比如我这里的设计是用户从网页发送的请求是走了node服务,node服务再发起SSH连接到目标机器,如果使用fastPut方法就一定存在临时文件,这样第一是速度慢,且实现上传进度的话,也并不准确了,毕竟是先分片上传到服务端,然后再分片上传到服务器,两个过程是割裂的。因此像我这里的场景,更适合使用put方法。

  2. put支持的流写法确保是可读流即可

  3. 这里举个例子是网页发起的WS传输数据构造的可读流,这样前端发出的数据片,直接流化发送到目标机器,本身在node服务端不做任何其它处理

  4. 上传文件默认会有权限,这里建议设置为0o644 ,该值参考的FileZilla-SFTP上传后给予的权限设定。

    • 644即rw-r--r--,用户自己有读写权限,组/其他只有读权限

get/fastGet

与上传类似,如果需要中转到前台,可以使用get方法,构建可写流。

限速

有时为了安全,需要对上传下载进行限速,做法如下。注意,限速需要流化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const Throttle = require('throttle');

const throttleStream = new Throttle(1024 * 1024); // 1MB
this.conn
.put(throttleStream.pipe(stream), data.path, {
writeStreamOptions: {
autoClose: false,
mode: 0o644,
},
readStreamOptions: {
autoClose: false,
},
pipeOptions: {
end: false,
},
})

取消

在上传下载过程中,突然想取消了,做法是直接断开SFTP连接,然后重新连接。

写在最后

iTerm2相比较Mac自带的Terminal个人觉得还是很强大的,这里总结下使用中的一些设置/技巧。

App完整设置过多,这里并不一一赘述,只hightlight下我个人认为重要的一些设定

基本设定

主题推荐设置为Minimal

终端会有沉浸式体验,没有独立的头部工具栏

https://static.1991421.cn/2022/2022-06-12-102934.jpeg

badge设置

每个profile进行badge设置,便于区分会话/机器,注意badge设定是by profile,并不对所有机器work。

https://static.1991421.cn/2022/2022-06-12-103252.jpeg

缺省显示timestamp

很多时候我想知道命令执行的大概时间,因此默认开启了右侧的时间戳显示

https://static.1991421.cn/2022/2022-06-12-103529.jpeg

Status bar开启

终端会话可以显示部分数据信息,比如内存占用情况/电池电量等

https://static.1991421.cn/2022/2022-06-12-103741.jpeg

https://static.1991421.cn/2022/2022-06-12-103843.jpeg

设置同步/保存

比如我自己有多台Mac设备,我希望iTerm2设置可以多设备自动同步,因此这里可以进行下设定,只需要将配置文件保存到iCloud的云盘,另一台Mac-iTerm2下加载即可。

https://static.1991421.cn/2022/2022-06-12-104334.jpeg

无限回滚-Unlimited scrollback

有时,我们的终端输出错误很长,如果想上滚动,看到完整的输出,需要进行下设定
Unlimited scrollback

https://static.1991421.cn/2022/2022-06-12-105930.jpeg

Cursor guide设定

光标所在行会有不同背景色进行高亮显示

https://static.1991421.cn/2022/2022-06-13-125026.jpeg

https://static.1991421.cn/2022/2022-06-13-125042.jpeg

集成工具

iTerm2强大除了本身这些feat外还可以再集成下以下几个工具,变的更好用

oh my zsh

zsh是很强大的shell,而oh my zsh让这一切更好用,更好看。

  1. 访问官网
  2. 安装推荐主题即可

zsh插件推荐

1
2
3
4
5
6
7
8
9
10
11
12
git
git-extras
zsh-syntax-highli
zsh-autosuggestio
autojump
jhipster
docker
docker-compose
spring
cask
macos
colored-man-pages

tmux

tmux可以解决会话保存/恢复,详细介绍可以看下我的另一篇总结,这里简单描述下

  1. iTerm2下全局设定

https://static.1991421.cn/2022/2022-06-12-104520.jpeg

  1. 目标机器安装tmux
  2. profile登陆机器时设置命令进行开启

ssh -p 22 -t root@188.146.132.160 "tmux -CC attach || tmux -CC"

https://static.1991421.cn/2022/2022-06-12-104849.jpeg

Alfred

Alfred用户集成后,可以直接在输入框里输入命令后唤起iTerm2执行

  1. 拷贝脚本内容

  2. Alfred- Features-Terminal

    https://static.1991421.cn/2022/2022-06-12-105621.jpeg

其它

Dynamic Profile

iTerm2下经常多服务器终端操作存在一个问题即如何复用profile配置,比如szrz的trigger支持,比如按键设置。

解决方案就是iTerm2 Dynamic Profile

配置

  1. cd ~/Library/Application\ Support/iTerm2/DynamicProfiles
  2. 创建iterm2-profile-template.json
  3. 配置iterm2-profile-template.json,具体profile配置项,可以UI上配置一个目标的,选择导出json,拷贝需要的配置项到template文件中去
    • 放置一个我的模版,供参考
  4. UI操作拷贝目标配置项
    • 选中模版profile
      image
    • 选中需要拷贝的类别项目
      当前profile也并非所有配置都支持拷贝
    • 选中拷贝到的目标profile,支持多选
      image

如此一来,即解决profile配置的复用问题

Dynamic Profile Parent Name

profile模版本身也支持动态继承,配置方式如上,只是多了2个字段Dynamic Profile Parent NameDynamic Profile Parent GUID来标明继承关系

  1. name/guid任选其一配置即可
  2. template中profile为list,因此需要注意配置放置顺序,父在前,子继承在后
  3. GUID的生成可以使用命令行工具uuidgen

推荐将profile作软链接,同步到云盘,方便复用。

ln -s "$HOME/Library/Mobile Documents/com~apple~CloudDocs/conf/iTerm2/iterm2-profile-template.json" "$HOME/Library/Application Support/iTerm2/DynamicProfiles/iterm2-profile-template.json"

Semantic History

iterm2终端下点击不同文件时,执行不同动作。🚀

脚本安装,戳这里

Triggers

简单的文件上传下载使用SZRZ会比单独使用FileZilla方便的多

https://static.1991421.cn/2022/2022-06-12-112714.jpeg

https://static.1991421.cn/2022/2022-06-12-112553.jpeg

写在最后

如何iTerm2还是很强大的吧,搞起。

小程序中存在绘制海报需求,大致是请求多张Web图片,合成绘制海报,用户可以保存到手机,然后分享朋友圈等。

当前存在的问题是有时候绘制时发现黑屏。因此这里分析解决下。

黑屏效果如下

阅读全文 »

工作中经常使用会议App,我当前工作中使用腾讯会议,之前工作中是Zoom。

常见的场景是同事会发出来会议邀请信息,我需要这样操作,手动拷贝其中的会议ID=>手动唤起会议App=>输入会议ID,如果拷贝到输入中出现空格/特殊字符等,还需单独处理下。由此可见这个过程麻烦,因此这里考虑使用workflow优化下整个流程。

效果

https://static.1991421.cn/2022/2022-05-28-124435.gif

选中会议信息文本,唤起text action,选择join meeting即可。当然也可以拷贝会议文本信息,唤起Alfred,输入关键词 meeting 回车。

下载链接

实现基础

  1. 唤起某个App且执行某个操作,一般是URL Scheme或者就是AppleScript。

    比如腾讯会议/Zoom均提供了URL Scheme支持,所以有实现基础,但TeamViewer/Teams没有提供,所以目前无法支持。

1
2
3
4

wemeet://page/inmeeting?meeting_code=$CODE

zoommtg://$org/join?action=join&confno=$confno&pwd=$pwd
  1. 依赖NodeJS

    个人相对熟悉JS,因此这里使用JS解决文本匹配转化问题。