CentOS7自建Anki同步服务器(python3)

CentOS7自建Anki同步服务器(python3)

什么是Anki

Anki是一个帮助记忆的Flash Card(教学卡片)软件,比如正面是英语单词,背面显示意思,然后让你选择,你觉得这个单词是容易、困难、或者完全不会,根据你选择的难易程度,这个单词会在接下来的不同时间出现,比如你点的困难,它可能1分钟后又出现了,如果你选的简单,它可能几天后才显示,而具体要几天后才出现这个是可以自己设置的。

Anki是开源的软件,使用python编写,在Windows、Mac、Linux三大平台通用,iOS和Android也有对应的软件,另外还有Web版,除了iOS版之外的所有版本都是免费的。

iOS版收费,是因为电脑版和iOS版都是同一个作者,他是全职做这个的,所以必须要有收入,好像是162还是163块RMB来着,安卓版免费是因为安卓版是另一个业余团队做的,所以安卓版可以自定义同步服务器而iOS版不可以。

Anki官网:https://apps.ankiweb.net
可以看看这些介绍的文章:https://zhuanlan.zhihu.com/-anki

自建AnkiServer原因

默认的Anki服务器同步很慢,而且据说这是个人项目,数据在别人手里也不可靠,说不定哪天丢了也有可能,所以我们自己搭建自己的服务器。但有个缺点就是iOS版的Anki不支持自定义服务器,因为iOS版是官方出品,

AnkiServer github

Anki和anki-sync-server都是python写的,这是python3版本的:anki-sync-server,由于python2版本的AnkiServer已经没有人维护,所以我们最好使用python3版本的。

安装epel

如果你不确定是否安装过epel,运行以下命令安装(如果已经安装它会自动识别,不会重复安装的):

yum -y install epel-release

安装python3

执行以下命令,搜索python3版本:

yum search python3

搜索结果可能有python34-xxxxpython36-xxxx等等,这个34,36表示3.4,3.6版本,安装其中最新的版本(当前2019.03.13,最新是python36),所以我们安装python36:

yum -y install python36

如果以后有37甚至38,安装的时候把36改成37或38即可。

安装后执行以下命令以确认是否安装成功(如果正常,则会出现Python 3.6.x的版本版本,同理,如果你以后有新版本python37,那么出来的就应该是Python 3.7.x):

python36 -V

安装pip3

从python官网下载get-pip.py(这个只是暂时使用的,可以下载到任何地方,使用完就可以删除):

wget https://bootstrap.pypa.io/get-pip.py

使用python36运行get-pip.py,以安装python36对应的pip3(注意此时要在get-pip.py所在的目录下执行以下命令):

python36 get-pip.py

安装完成后,python36的pip应该会被安装到以下路径:

/usr/local/bin/pip

为了与python2.7的pip区分,我们把它修改一下名字:

mv /usr/local/bin/pip /usr/local/bin/pip3

运行pip3 -V试试,如果是指向python3.6的路径,说明一切正常。

然后就可以删除get-pip.py文件了:

rm get-pip.py

使用pip3安装webob依赖:

pip3 install webob

安装AnkiServer

由于AnkiServer是用python语言写的,python是脚本语言,所以,所谓的安装,就是把代码clone到本地,你想放在哪里都无所谓,我是放在/usr/local/anki-sync-server下,你也可以放在~/anki-sync-server下:

git clone https://github.com/tsudoko/anki-sync-server.git /usr/local/anki-sync-server

安装Anki

注意,AnkiServer是AnkiServer,Anki是Anki,这不是同一个东西,AnkiServer依赖于Anki,所以下载AnkiServer后,还必须下载Anki,Anki下载后要放在anki-sync-server目录下的一个叫anki-bundled的目录里。

那Anki从哪里下呢?
方法一:因为Anki本身也是python写的,它也是开源的,它的github地址是:https://github.com/dae/anki, 所以你可以从这个地址里clone到anki-bundled里。
方法二:直接下载anki-sync-server项目下的anki-bundled @ cca3fcb,它其实本身就是Anki的github源码链接,只不过这个链接不是Anki的主分支,而是anki-sync-server作者测试过的可用的稳定分支,所以我们就使用这种方法下载,不要用方法一。

疑问

问:有人可能会觉得奇怪,为什么我clone完anki-sync-server后,anki-bundled是空的?为什么它里面的内容不会下载下来?

答:因为它是一个链接,属于另一个版本库,你可以点它试试,它已经跳转到anki项目里了


进入anki-sync-server目录,注意你自己下载的目录也许跟我的不同:

cd /usr/local/anki-sync-server

运行以下命令,用于下载git子模块代码(即Anki的代码,这一步执行完,就安装了Anki了):

git submodule update --init

进入以下目录,你会发现已经不是空的了:

cd anki-bundled

删除“requirements.txt”文件中的“pyaudio”:
先用以下命令打开文件,然后用方向选把光标指向pyaudio那一行,然后按dd即可删除,最后输入:x然后回车(注意,都要英文输入法下操作):

vim requirements.txt

执行以下语句,用于安装Anki的依赖:

pip3 install -r requirements.txt

vim编辑ankisyncctl.py文件,它的第一行默认是:

#!/usr/bin/env python

把它改成:

#!/usr/bin/env python36

表示用python36运行ankisyncctl.py脚本。

这样就算安装调试完了,运行以下命令查看使用方法:

./ankisyncctl.py usage

如果正常,出来的结果应该是这样的:

usage: /usr/local/bin/ankisyncctl <command> [<args>]

Commands:
  adduser <username> - add a new user
  deluser <username> - delete a user
  lsuser             - list users
  passwd <username>  - change password of a user

到这里,AnkiServer就安装完毕了。

使用ankisyncctl.py(主要是管理账号)

添加一个用户名为“zhangsan”的用户(它会让你输入密码):

./ankisyncctl.py adduser zhangsan

查看已添加的用户列表:

./ankisyncctl.py lsuser

修改用户名为“zhangsan”的用户的密码:

./ankisyncctl.py passwd zhangsan

删除用户名为“zhangsan”的用户:

./ankisyncctl.py deluser zhangsan

因为没有修改用户名功能,如果你要修改用户名,那么你要先删除,再重新添加。

启动anki-sync-server

执行以下命令启动anki-sync-server,它的服务名称叫ankisyncd,注意,以下命令必须在anki-sync-server文件夹下执行,因为它要找该文件夹下的ankisyncd文件夹的:

python36 -m ankisyncd &

如果启动正常,它应该会有类似以下的提示:

[2019-03-14 06:28:17,456]:INFO:ankisyncd:Loaded config from /usr/local/anki-sync-server/ankisyncd.conf
[2019-03-14 06:28:17,461]:INFO:ankisyncd:Serving HTTP on 0.0.0.0 port 27701...

查看是否正常启动:

ps -ef | grep ankisyncd

如果你看到有类似以下的结果,说明运行正常:

root      5838  3130  0 06:28 pts/0    00:00:00 python36 -m ankisyncd

注意:一般情况下,在启动命令后加&表示在后台启动,但是,在这里不行,目前我也不知道原因,如果你想后台启动,有两种方法,一种是使用nohub(注意该命令还是必须在anki-sync-server文件夹下执行):

nohup python36 -m ankisyncd >> /var/log/ankisyncd.log 2>&1 &

注意,即便是用nohub,也不能直接关闭窗口,而是用exit命令来退出窗口,你需要执行两次exit命令才能退出窗口。

然后把它加入开启启动:

echo "nohup python36 -m ankisyncd >> /var/log/ankisyncd.log 2>&1" >> /etc/rc.d/rc.local

第二种后台运行的方法就是使用supervisor,注意,如果你用了“nohub”这种方法,下边的“使用supervisor管理进程”就不用看了,两种方法选一种。

关闭防火墙

为了避免端口不开放导致的问题,使用以下命令关闭防火墙:

systemctl stop firewalld
systemctl disabled firewalld

当然如果你懂防火墙怎么用,你也可以开放27701端口。

检测自建AnkiServer是否能正常访问

假设你的服务器ip是12.34.56.78,那么你在浏览器访问http://12.34.56.78:27701,会显示Anki Sync Server,那就说明是正常的,如果打不开,那就有问题。

电脑端设置

以下配置在mac和win测试通过(版本为2.1.11),由于我没有Linux桌面版Linux系统,所以未在Linux上测试,不过原理都是一样的。

注意:由于我本地都是安装的英文版的,所以下面我说的点击哪个菜单我都是用英文的,如果你安装的中文版,请自行对应,相信这几个英文难不倒你。

打开Anki,点击顶部菜单栏的ToolsAdd-ons会打开插件窗口,然后再点击插件窗口的View files按钮,会打开插件安装目录。在该目录下新建一个文件夹ankisyncd,然后在里面新建一个文件,命名为__init__.py,打开__init__.py,把以下命令粘贴进去,然后把其中的12.34.56.78修改成你服务器的ip,如果你修改过ankisyncd.conf里的“port”(即端口),这里的端口也要与ankisyncd.conf中的“port”对应,然后保存:

import anki.sync, anki.hooks, aqt

addr = "http://12.34.56.78:27701/" # put your server address here
anki.sync.SYNC_BASE = "%s" + addr
def resetHostNum():
    aqt.mw.pm.profile['hostNum'] = None
anki.hooks.addHook("profileLoaded", resetHostNum)

最后重启anki,即把anki软件关掉,再重新打开。

点击Sync(即“同步”)测试,如果正常,它会提示你输入账号密码,这个账号密码就是你前边用./ankisyncctl.py adduser添加的账号和密码了。

安卓端

点击左上角三道杠→点击设置→点击高级设置→点击自定义同步服务器→勾选使用自定义同步服务器,然后下边有同步地址媒体文件同步地址
同步地址:http://12.34.45.78:27701(把ip改成你的服务器ip)
媒体文件同步地址:http://12.34.45.78:27701/msync(改成你的服务器ip),即媒体文件同步地址是在同步地址后面添加/msync(其实这个名字是在服务器的配置文件ankisyncd.conf中的base_media_url选项指定的)。

设置好之后,点击同步按钮,正常的话会让你输入账号密码,输入与电脑端相同的账号密码,即可进行同步。

iOS端

App不支持,无解,换手机吧😄

使用supervisor管理进程

这一步必须做,如果不做,anki服务器将无法后台运行,我用了&符号结尾也不行,倒是没有试nohup,不过最好还是用superviosr吧。


安装supervisor:

yum -y install supervisor

编写配置文件:

vim /etc/supervisord.d/ankisyncd.ini

i切换到输入状态,把以下内容粘贴进去,输入:x保存:

[program:ankisyncd]
command=/bin/python36 -m ankisyncd              ; the program (relative uses PATH, can take args)
;process_name=%(program_name)s ; process_name expr (default %(program_name)s)
;numprocs=1                    ; number of processes copies to start (def 1)
directory=/usr/local/anki-sync-server/                ; directory to cwd to before exec (def no cwd)
;umask=022                     ; umask for process (default None)
;priority=999                  ; the relative start priority (default 999)
autostart=true                ; start at supervisord start (default: true)
autorestart=true              ; retstart at unexpected quit (default: true)
startsecs=3                  ; number of secs prog must stay running (def. 1)
;startretries=3                ; max # of serial start failures (default 3)
;exitcodes=0,2                 ; 'expected' exit codes for process (default 0,2)
;stopsignal=QUIT               ; signal used to kill process (default TERM)
;stopwaitsecs=10               ; max num secs to wait b4 SIGKILL (default 10)
;user=chrism                   ; setuid to this UNIX account to run the program
;redirect_stderr=true          ; redirect proc stderr to stdout (default false)
stdout_logfile=/var/log/ankisyncd.log        ; stdout log path, NONE for none; default AUTO
;stdout_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stdout_logfile_backups=10     ; # of stdout logfile backups (default 10)
;stdout_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stdout_events_enabled=false   ; emit events on stdout writes (default false)
stderr_logfile=/var/log/ankisyncd.error.log    ; stderr log path, NONE for none; default AUTO
;stderr_logfile_maxbytes=1MB   ; max # logfile bytes b4 rotation (default 50MB)
;stderr_logfile_backups=10     ; # of stderr logfile backups (default 10)
;stderr_capture_maxbytes=1MB   ; number of bytes in 'capturemode' (default 0)
;stderr_events_enabled=false   ; emit events on stderr writes (default false)
;environment=A=1,B=2           ; process environment additions (def no adds)
;serverurl=AUTO                ; override serverurl computation (childutils)

用以下命令打开supervisord的配置文件:

vim /etc/supervisord.conf

找到[inet_http_server],把它下面的三个参数修改成以下的样子,其中username和password修改成你自己想要的用户名和密码:

[inet_http_server]
port=*:9001
username=zhangsan
password=192837465

启动supervisord:

/usr/bin/supervisord -c /etc/supervisord.conf

把supervisord加入开机自启动:

vim /etc/rc.local

然后把下面这句添加进去:

/usr/bin/supervisord -c /etc/supervisord.conf

浏览器里输入:http://12.34.56.78:9001(ip要修改成你服务器的ip), 输入上边设置的账号和密码即可从页面中访问查看你的anki同步服务进程ankisyncd
Xnip2019-03-15_02-48-41.jpg

如果想更多的了解supervisor,请查看:使用supervisor管理进程

打赏

1
Leave a Reply

avatar
1 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
gakki Recent comment authors

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
Notify of
gakki
Guest
gakki

谢谢博主,成功在小鸡上搭建anki服务,而且PC端anki 2.1.11也能同步使用了,ankidroid也ok

扫码在手机查看
iPhone请用自带相机扫
安卓用UC/QQ浏览器扫

CentOS7自建Anki同步服务器(python3)