Ekans歌词白嫖器
1 安装
2 网站抽象
2.1 引入接口
2.2 必要类型定义
专辑结构
歌手结构
歌曲结构
搜索结果结构
查询结构
2.3 接口定义
->搜索
->下载歌词
->下载歌曲
3 添加新网站
8.6

Ekans歌词白嫖器

XG.Ley

歌词白嫖下载器。

 (require ekans) package: ekans

1 安装

$ raco pkg install ekans

2 网站抽象

ekans统一了网站行为,只要每个网站实现了接口,就能在界面上使用,无须处理其他事务。

2.1 引入接口

引入"base/main.rkt"即可,需要注意的是,一般网站文件都在"site"。可能需要这样写:

(require "../base/main.rkt")
 
;;; 剩余逻辑……

然后得到了gen:Site、必要类型定义,可以直接引用。

2.2 必要类型定义

struct

(struct 专辑结构 (id 名称))

  id : any/c
  名称 : string?
歌曲所在专辑。

struct

(struct 歌手结构 (id 名字))

  id : any/c
  名字 : string?
歌曲演唱者信息。

struct

(struct 歌曲结构 (id 名称 歌手列表 专辑))

  id : any/c
  名称 : string?
  歌手列表 : (listof 歌手结构?)
  专辑 : 专辑结构?
一首歌曲所有信息。

歌曲有可能由多位艺人演唱,故而是个列表。

struct

(struct 搜索结果结构 (歌曲列表))

  歌曲列表 : (listof 歌曲结构?)
歌曲查询结果,不需要分页,取需要部分。

struct

(struct 查询结构 (歌曲 歌手))

  歌曲 : string?
  歌手 : string?
这是用户查询输入,用户点击“搜索”时,会将该类型传到对应函数。

2.3 接口定义

一共有三个接口可以实现,每个接口都有默认实现,所有默认实现都是提示“未定义”,如果要实现正确的功能,必须写出正确的实现方法,不能使用默认实现。

procedure

(->搜索 Site 查询)  搜索结果结构?

  Site : any/c
  查询 : 查询结构?
实现歌曲搜索逻辑。

用户点击“搜索”,触发该接口。

procedure

(->下载歌词 Site 歌曲)  string?

  Site : any/c
  歌曲 : 歌曲结构?
实现歌词下载逻辑。

用户点击“查看歌词”,触发该接口。

procedure

(->下载歌曲 Site 歌曲)  input-port?

  Site : any/c
  歌曲 : 歌曲结构?
实现歌曲下载逻辑。 歌曲一般都由网络下载,所以仅返回一个"input-port"即可,剩余部分都由其他代码处理了。

用户点击“下载歌曲”,触发该接品。

3 添加新网站

"site/"目录有着每个网站实现,需要添加的网站文件都能在此找到。我们以虚拟的cc网站为例。

;;; cc.rkt
(require "../base/type.rkt") ; 引入必要的依赖。
 
(provide site) ; 仅导出结构体构造函数。
 
(struct site []  ; 置空即可,一般不会有额外参数。
  #:methods gen:Site [])

如此我们就能使用这个新类型。此时启动程序,我们不能看到新网站选项,需要为它定义一个网站名称,并写入到选择列表中。接下来我们打开"site/main.rkt"

(require (rename-in "./netease.rkt"
                    (site netease-site))
         (rename-in "./kugou.rkt"
                    (site kugou-site)))
                ;;; 新的站点写在下面
                (rename-in "./cc.rkt"
                                   (site cc-site))
 
;;; 省略其他代码
 
(define site-hash
  (make-hash `((网易云音乐 . ,(netease-site))
                           (cc歌词下载站 . ,(cc-site))
               (酷狗音乐 . ,(kugou-site)))))
 

此时打开程序就能看到我们的新网站了,其他功能也能使用。由于全部使用默认实现,每个操作都会提示“未定义”。为了正常使用,务必要实现对应接口。

更加具体实现,可以参考"site/netease.rkt"