前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >使用Go语言批量同步微信读书笔记到Flomo

使用Go语言批量同步微信读书笔记到Flomo

作者头像
博文视点Broadview
发布2022-08-26 18:22:45
发布2022-08-26 18:22:45
1K00
代码可运行
举报
运行总次数:0
代码可运行

👆点击“博文视点Broadview”,获取更多书讯

“微信读书”和“Flomo”是我们常用的阅读和卡片记忆法软件。

在实际使用时,我们经常会有这样的需求:将微信读书中划线的笔记导入Flomo。传统的做法是先复制文字内容,然后打开Flomo,粘贴文字内容,输入适当的标签后保存,然后回到微信读书中继续阅读。

这一套动作下来,不仅要点击和切换好几次,连续阅读的体验也被破坏了。

恰好,Flomo提供了API,允许开发者通过API添加内容。按照官方文档的指引,使用Go语言就可以实现将微信读书中的笔记批量同步到Flomo的功能。

下面就将方法分享给大家!

01

操作方法

具体来说,实现这一功能的小程序是一个命令行应用程序。在编译出的可执行文件后添加help参数可以看到具体的使用方法,如下图所示。

首先,准备好要提交的笔记内容,从微信读书App中直接将内容复制出来,然后保存到纯文本文件中,比如下面这样。

显然,这里有3条划线笔记,意味着最终将添加3条Flomo。

接下来,想想这3条笔记的标签,我们也可以一次性添加多个标签。

最后,执行以下命令,在若干日志输出后,提示“全部笔记提交完成”,如下图所示。

代码语言:javascript
代码运行次数:0
复制
main笔记,认知 C:\Users\wh199\Desktop\认知红利笔记.txt

打开Flomo,就可以看到刚刚提交的3条笔记了。

如此一来,我们可以专注于阅读和画线,在一个阅读阶段完成后,导出一次笔记。运行一次程序,相应的笔记内容就会被批量同步到Flomo中。是不是特别方便?

02

核心技术点

使用上述小程序确实能省去很多操作,节约很多时间。开发这个程序的过程也非常简单(仅需30分钟左右)。下面我们来细数这个小程序的核心技术点。

  • 命令行参数读取:用户需要“告知”程序读取哪个文件,添加哪些标签;
  • 字符串解析与文件读取:确保将文本文件中的笔记准确地读取出来;
  • 网络请求和解析:将读取出来的每条笔记通过Flomo API进行提交。

就这些吗?对!就只有这些!

03

代码实现

下面,我们基于代码开发,一步步实现这个小程序。

命令行参数读取

Go SDK中内置了os包os.Args,它可以实现对执行参数的获取。这是一个[]string类型的变量,里面包含着该程序执行时给定的参数。

如果不添加任何参数,执行main.exe的方式为:

代码语言:javascript
代码运行次数:0
复制
main

此时,os.Args中包含1个元素——main。

如果添加了参数,如“help”,执行main.exe时,方式为:

代码语言:javascript
代码运行次数:0
复制
main help

此时,os.Args中包含2个元素——main和help。

由此,我们便可实现以下功能:输出程序的“帮助文档”、解析标签组的内容、解析文件路径。

具体代码如下:

代码语言:javascript
代码运行次数:0
复制
if len(os.Args) >= 2 {if os.Args[1] == "help" {fmt.Println("▶▶ 当存在2个命令行参数时:")fmt.Println("▶▶ 第一个参数是标签,多个标签以逗号隔开;")fmt.Println("▶▶ 第二个是文件输入源,要求同目录下的完整文件名。")fmt.Println("��� 注意1:文件要求UTF-8编码,内容直接粘贴微信读书导出的内容即可。��� ")fmt.Println("��� 注意2:单日最多可上传100条memo。��� ")fmt.Println("。◕‿◕。")return}    // 解析标签tags = "#" + strings.ReplaceAll(os.Args[1], ",", " #")fmt.Println("笔记标签为:", tags)    // 读文件,并获取笔记信息singleExcerpts = readFile(os.Args[2])fmt.Println("总共笔记数量:", len(singleExcerpts))    // 循环方式,提交每条笔记for i := 0; i < len(singleExcerpts); i++ {if singleExcerpts[i] != "" && singleExcerpts[i] != "\n" {singleExcerpts[i] = strings.ReplaceAll(singleExcerpts[i], ">>", "")fmt.Println("--------------------------------------------------")fmt.Printf("提交第%d条笔记\n%s\n", i, singleExcerpts[i])upload(tags, strings.TrimSuffix(singleExcerpts[i], "\n"))fmt.Println("--------------------------------------------------")}}fmt.Println("全部笔记提交完成")}

这段代码实际上就是main()函数的全部内容,它实现了程序执行的完整流程。

解析标签无须多说,当我们在命令行中给定“笔记,认知”作为标签时,程序将替换“,”为“ #”(注意:此处时空格加上井号)。再回到开头补足首个标签的“#”,最终保存到tags中,成为:“#笔记 #认知”。

文件路径保存在os.Args[2]中,readFile()是读文件,并解析每条笔记的函数,它最终将返回[]string类型值。于是,singleExcerpts便包含了所有的笔记,它是[]string类型的变量。

最后,根据singleExcerpts的长度,通过for结构的循环进行提交。upload()函数是具体的提交逻辑,需要标签和单条笔记的文本内容。

读取文件、解析字符串

文件的读取和全部笔记的分割通过readFile()函数来完成。该函数需要传入完整的文件路径,最终返回包含分割好的每条笔记的string类型切片。

读文件用到两个包,一个是os,另一个是bufio。

仔细观察导出的文本内容,一开始是书名、作者和笔记个数统计,“◆ ”开头表示章节名,“>> ”开头表示单个划线内容。这三者之中,我们只取最后一类即可。

因此,思路是这样的:按行读取文本文件,遇到“◆ ”时,表示接下来将会有具体的划线笔记。遇到“>> ”时,将其汇总到另一个string类型变量中(fullContentFiltered)。重复上述过程,直到文件末尾。最后,以“>> ”为依据,对fullContentFiltered进行拆分,并辅以Trim操作,即可得到单条笔记了。

完整代码如下:

代码语言:javascript
代码运行次数:0
复制
// 读文件内容(UTF-8编码兼容)func readFile(filepath string) []string {   var returnData []string   file, err := os.Open(filepath)   if err != nil {      panic(err)   }   defer file.Close()   fileScanner := bufio.NewScanner(file)

   fullContentFiltered := ""   contentBegin := false

   for fileScanner.Scan() {      singleLine := fileScanner.Text()      if strings.HasPrefix(singleLine, "◆ ") || strings.HasPrefix(singleLine, ">> ") {         contentBegin = true      }      if !strings.HasPrefix(singleLine, "◆ ") && singleLine != "" {         if contentBegin {            fullContentFiltered += singleLine + "\n"         }      }   }   fullContentFiltered = strings.ReplaceAll(fullContentFiltered, ">> ", ">>")   fullContentFiltered = strings.TrimSuffix(fullContentFiltered, "\n")   fullContentFiltered = strings.TrimPrefix(fullContentFiltered, " ")   returnData = strings.Split(fullContentFiltered, ">>")   return returnData}

网络请求和解析

最后就是网络请求,这里要结合Flomo的官方文档,并使用http、ioutil和json包进行。这一步较为简单,这里就不再详述了,具体代码如下:

代码语言:javascript
代码运行次数:0
复制
// 请求flomo接口,提交数据func upload(tags string, content string) {   content = content + "\n\n" + tags   uploadDataObj := Content{      Content: content,   }   uploadData, _ := json.Marshal(uploadDataObj)   resp, err := http.Post("https://flomoapp.com/iwh/xxxxxx/",      "application/json",      strings.NewReader(string(uploadData)))   if err != nil {      fmt.Println(err)   }   defer resp.Body.Close()   body, err := ioutil.ReadAll(resp.Body)   if err != nil {      panic(err)   }   fmt.Println(string(body))}

到此,整个小程序的代码实现就完成了。

04

还能做什么?

通过实现这样一个简单的程序,我们能得到什么灵感呢?做些改进,通过书名自动添加标签?或是增加更多的字符串解析方法,做一个更通用的程序?或是绘制一个GUI,让用户自己填写识别字符串的正则表达式?

Go语言可以做服务器软件,做起客户端软件来也丝毫不含糊。高效的开发效率不仅可以节省开发者的时间,还“鼓励”着人们亲自动手,方便自己的生活与学习。毕竟,自己写一个这样的小工具比找一个现成的更省时间。

想要使用Go语言实现更多有意思的项目吗?

欢迎阅读《Go语言从入门到项目实战(视频版)》一书了解更多哦~~

粉丝专享六折优惠,快快扫码抢购吧!

发布:刘恩惠

审核:陈歆懿

代码语言:javascript
代码运行次数:0
复制
如果喜欢本文欢迎 在看丨留言丨分享至朋友圈 三连
 热文推荐  
十年了,数字化浪潮带来了怎样的巨变?
何去何从的并行计算
“副业焦虑”席卷Z世代,今天你的副业失败了吗?
横跨Java后端关键技术,Spring Boot终极体系做到了

▼点击阅读原文,了解本书详情~

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-08-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 博文视点Broadview 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 操作方法
  • 核心技术点
  • 代码实现
  • 还能做什么?
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档