搭建anki同步服务器与常用插件

Anki是一个根据艾宾浩斯曲线很好用的学习软件,但是官方那个同步服务器很垃圾,所以自建一个很有必要。

一、搭建anki-sync-server

直接docker安装,快捷无脑

docker run -d --name anki-container \
  -p 27701:27701 \
  -v /www/wwwroot/anki.linjoey.cn/:/app/data \
  kuklinistvan/anki-sync-server:latest

这里的映射路径换成自己的,不要直接复制用

二、管理同步用户

# Docker进入容器
docker exec -it anki-container /bin/sh

# 查看帮助
./ankisyncctl.py --help
usage: ./ankisyncctl.py <command> [<args>]

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

# 增加用户admin,这里会提示输入密码
./ankisyncctl.py adduser admin
Enter password for test:

# 查看用户
./ankisyncctl.py lsuser
admin

# 删除用户
./ankisyncctl.py deluser admin
admin

三、Windows与安卓版应用配置

iOS是付费软件且好像不支持这个同步服务,自己想办法去吧。

0、版本要求

根据github文档,版本最好为Windows的2.1.19以及安卓的2.9.1。
我放在网盘里面了,需要可下:点此下载

1、Windows配置

安装后打开工具 - 附加组件 - 获取插件 - 输入代码358444159,之后双击组件,在配置文档里写入:

{
    "syncaddr": "https://公网IP:27701/"
}

如果前面改了端口号或者自己做了反向代理自动填成对应的正确设置即可。

新版的配置方法:
如果非用新版,可参考下面方法:
从 Anki 中打开插件目录,创建 ankisyncd 文件夹,然后添加 __init__.py 文件,写入内容:
import os

addr = "http://127.0.0.1:27701/" # put your server address here
os.environ["SYNC_ENDPOINT"] = addr + "sync/"
os.environ["SYNC_ENDPOINT_MEDIA"] = addr + "msync/"
重新打开 应用 即可使用刚刚部署的同步服务。

2、安卓配置

安卓的相对简单一些,直接打开设置 - 高级设置 - 自定义同步服务器,同步地址填IP:端口号,文件同步地址填IP:端口号/msync,最好都用 https 加密协议。

四、一些好用的其他插件

注意,插件是不会同步的,所以插件最好本地备一份。

1、Enhance main window


这是一个主页面增强插件,可以让各个牌组的情况更加清晰。

插件主页:https://ankiweb.net/shared/info/877182321
安装代码:877182321

一套知乎大佬 @叶峻峣 提供的配置方案,直接拿来用了。

{
    "book symbol": "{",
    "cap value": null,
    "color empty": "green",
    "color empty descendant": "green",
    "color marked": true,
    "columns": [
        {
            "absolute": true,
            "color": "red",
            "description": "Number of review you will see today (new, review and learning)",
            "header": null,
            "name": "today",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "green",
            "description": "Review cards cards you will see today (and the ones you will not see today)",
            "header": null,
            "name": "review",
            "overlay": null,
            "percent": false,
            "present": true,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "orange",
            "description": "Cards in learning (either new cards you see again, or cards which you have forgotten recently. Assuming those cards didn't graduate)",
            "header": null,
            "name": "learning card",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "orange",
            "description": "Review which will happen later. Either because a review happened recently, or because the card have many review left.",
            "header": null,
            "name": "learning later",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "orange",
            "description": "Cards in learning which are due now. If there are no such cards, the time in minutes or seconds until another learning card is due",
            "header": null,
            "name": "learning now",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "orange",
            "description": "Cards in learning which are due now (and in parenthesis, the number of reviews which are due later)",
            "header": null,
            "name": "learning all",
            "overlay": null,
            "percent": false,
            "present": true,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "green",
            "description": "Review cards which are due today (not counting the one in learning)",
            "header": null,
            "name": "review due",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "green",
            "description": "Review cards you will see today",
            "header": null,
            "name": "review today",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "blue",
            "description": "Cards that have never been answered",
            "header": null,
            "name": "unseen",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "blue",
            "description": "Unseen+ cards+ you will see today (what anki calls +new cards",
            "header": null,
            "name": "new",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "blue",
            "description": "Unseen cards you will see today (and those you will not see today)",
            "header": null,
            "name": "unseen new",
            "overlay": null,
            "percent": false,
            "present": true,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "grey",
            "description": "number of buried cards, (cards you decided not to see today)",
            "header": null,
            "name": "buried",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "brown",
            "description": "number of suspended cards, (cards you will never see unless you unsuspend them in the browser)",
            "header": null,
            "name": "suspended",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "black",
            "description": "Number of cards in the deck",
            "header": null,
            "name": "cards",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "black",
            "description": "Number of cards/note in the deck",
            "header": null,
            "name": "notes/cards",
            "overlay": null,
            "percent": false,
            "present": true,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "black",
            "description": "Number of cards/note in the deck",
            "header": null,
            "name": "notes",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "purple",
            "description": "Number of cards reviewed, not yet due",
            "header": null,
            "name": "undue",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "",
            "description": "Number of cards reviewed, with interval at least 3 weeks",
            "header": null,
            "name": "mature",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "pink",
            "description": " Number of cards reviewed, with interval less than 3 weeks,",
            "header": null,
            "name": "young",
            "overlay": null,
            "percent": false,
            "present": false,
            "subdeck": true
        },
        {
            "absolute": true,
            "color": "purple",
            "description": "Number of marked note",
            "header": null,
            "name": "marked",
            "percent": false,
            "present": true,
            "subdeck": true
        }
    ],
    "end symbol": ";",
    "ended marked background color": "yellow",
    "given up symbol": "/",
    "marked backgroud color": "powderblue",
    "option": true,
    "pause symbol": "=",
    "refresh rate": 30
}

2、Review Heatmap


这是一个统计功能的插件,有助于量化学习成果。

插件主页:https://ankiweb.net/shared/info/1771074083
安装代码:1771074083

五、牌组制作方法简述

1、批量制作普通正反面卡牌

  • 在Excel中分两列写好正面和反面的内容
  • 选中所有内容复制到记事本中,另存为,编码格式选择UTF-8
  • 打开anki,选择导入文件,类型选择基础,规则选择\t,导入即可。

2、批量制作填空题卡牌

  • 每张卡牌的内容放在单独一段,在WPS中用红色标记挖空的内容
  • 有个很坑的东西,由于WPS和Word都喜欢自作聪明地把换行符加颜色,所以需要先按红色格式把所有的^p替换成黑色的^p再进行操作
  • 按红色格式查找并替换,内容为英文格式符号:{{c1::^&}}
  • 把所有内容复制到记事本中,另存为,编码格式选择UTF-8
  • 打开anki,选择导入文件,类型选择填空题,规则选择\t,导入即可。

无标签