# fava-ghost
`fava-ghost`是一个为运行和管理[fava](https://github.com/beancount/fava)实例而设计的高效后台守护进程,它结合了 Docker 容器化技术,使得部署、更新和管理 fava 服务变得简单快捷。
## 特性
- **自动化同步**:自动从 git 仓库同步 fava 账本文件。
- **依赖性管理**:自动管理和安装 Python 依赖,确保 fava 运行环境始终为最新状态。
- **冲突解决**:在发现合并冲突时会提醒用户手动解决。
- **容器化**:使用 Docker 容器,简化部署和迁移。
# Beancount 项目准备
fava-ghost 并不强制用户使用特定的 fava / beancount 版本,所以用户需要在自己的项目中指定 fava / beancount 版本。fava-ghost 使用 `pip install -e .` 来安装 fava / beancount,所以你需要在你的项目中添加 `setup.py` 文件,内容如下:
```python
from setuptools import setup
setup(
install_requires=[
'fava==1.26.2',
'beancount==2.3.6',
],
)
```
# 使用
首先安装 fava-ghost:
```bash
pip install fava-ghost
```
fava-ghost 需要有读写仓库权限的 Github Credentials 来同步账本文件。你可以在 [这里](https://github.com/settings/tokens?type=beta) 申请一个 Github Fine-grained personal access token。然后启动 fava-ghost:
```bash
fava-ghost --repo-url https://github.com/REPO --repo-credentials GITHUB_TOKEN --repo-path PATH_TO_REPO
```
其中 PATH_TO_REPO 是你的账本仓库的本地路径,比如 `~/Documents/Beancount`。
就可以开始自动同步账本文件了。一旦启动,fava-ghost 会自动开始做如下事情:
1. clone 你的账本仓库到 PATH_TO_REPO
2. 在账本仓库下执行 pip 安装所需依赖
3. 启动 fava 服务
4. 每隔 10 秒尝试进行同步本地账本和代码仓库
# 同步策略
对于不同的情况,fava-ghost 会采取不同的同步策略:
1. 远程有更新,本地没有更新:自动 pull
2. 远程没有更新,本地有更新:自动 push
3. 远程和本地都有更新:执行 merge,如果没有冲突,则自动 push。如果有冲突,则需要用户手动编辑文件到文件中不存在冲突标记后,自动 push
# docker
fava-ghost 也可以通过 docker 运行。镜像是 `e7h4n/fava-ghost`。你可以通过如下命令运行:
```bash
docker run e7h4n/fava-ghost -d -p 5000:5000 --repo-url REPO_URL --repo-credentials GITHUB_TOKEN
```
通过 docker,你可以在任意一个环境下快速启动 fava 服务来托管你的 beancount 账本,无需解决环境问题。
Raw data
{
"_id": null,
"home_page": "https://github.com/e7h4n/fava-ghost",
"name": "fava-ghost",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.6, <4",
"maintainer_email": "",
"keywords": "beancount,fava,daemon,git sync",
"author": "e7h4n",
"author_email": "ethan.pw@icloud.com",
"download_url": "https://files.pythonhosted.org/packages/d7/70/ae83e4fdd867298147a5a252ed292f3e779e1f29b11d6f1b5f4d4542ceb7/fava-ghost-0.1.13.tar.gz",
"platform": null,
"description": "# fava-ghost\n\n`fava-ghost`\u662f\u4e00\u4e2a\u4e3a\u8fd0\u884c\u548c\u7ba1\u7406[fava](https://github.com/beancount/fava)\u5b9e\u4f8b\u800c\u8bbe\u8ba1\u7684\u9ad8\u6548\u540e\u53f0\u5b88\u62a4\u8fdb\u7a0b\uff0c\u5b83\u7ed3\u5408\u4e86 Docker \u5bb9\u5668\u5316\u6280\u672f\uff0c\u4f7f\u5f97\u90e8\u7f72\u3001\u66f4\u65b0\u548c\u7ba1\u7406 fava \u670d\u52a1\u53d8\u5f97\u7b80\u5355\u5feb\u6377\u3002\n\n## \u7279\u6027\n\n- **\u81ea\u52a8\u5316\u540c\u6b65**\uff1a\u81ea\u52a8\u4ece git \u4ed3\u5e93\u540c\u6b65 fava \u8d26\u672c\u6587\u4ef6\u3002\n- **\u4f9d\u8d56\u6027\u7ba1\u7406**\uff1a\u81ea\u52a8\u7ba1\u7406\u548c\u5b89\u88c5 Python \u4f9d\u8d56\uff0c\u786e\u4fdd fava \u8fd0\u884c\u73af\u5883\u59cb\u7ec8\u4e3a\u6700\u65b0\u72b6\u6001\u3002\n- **\u51b2\u7a81\u89e3\u51b3**\uff1a\u5728\u53d1\u73b0\u5408\u5e76\u51b2\u7a81\u65f6\u4f1a\u63d0\u9192\u7528\u6237\u624b\u52a8\u89e3\u51b3\u3002\n- **\u5bb9\u5668\u5316**\uff1a\u4f7f\u7528 Docker \u5bb9\u5668\uff0c\u7b80\u5316\u90e8\u7f72\u548c\u8fc1\u79fb\u3002\n\n# Beancount \u9879\u76ee\u51c6\u5907\n\nfava-ghost \u5e76\u4e0d\u5f3a\u5236\u7528\u6237\u4f7f\u7528\u7279\u5b9a\u7684 fava / beancount \u7248\u672c\uff0c\u6240\u4ee5\u7528\u6237\u9700\u8981\u5728\u81ea\u5df1\u7684\u9879\u76ee\u4e2d\u6307\u5b9a fava / beancount \u7248\u672c\u3002fava-ghost \u4f7f\u7528 `pip install -e .` \u6765\u5b89\u88c5 fava / beancount\uff0c\u6240\u4ee5\u4f60\u9700\u8981\u5728\u4f60\u7684\u9879\u76ee\u4e2d\u6dfb\u52a0 `setup.py` \u6587\u4ef6\uff0c\u5185\u5bb9\u5982\u4e0b\uff1a\n\n```python\nfrom setuptools import setup\n\nsetup(\n install_requires=[\n 'fava==1.26.2',\n 'beancount==2.3.6',\n ],\n)\n```\n\n# \u4f7f\u7528\n\n\u9996\u5148\u5b89\u88c5 fava-ghost:\n\n```bash\npip install fava-ghost\n```\n\nfava-ghost \u9700\u8981\u6709\u8bfb\u5199\u4ed3\u5e93\u6743\u9650\u7684 Github Credentials \u6765\u540c\u6b65\u8d26\u672c\u6587\u4ef6\u3002\u4f60\u53ef\u4ee5\u5728 [\u8fd9\u91cc](https://github.com/settings/tokens?type=beta) \u7533\u8bf7\u4e00\u4e2a Github Fine-grained personal access token\u3002\u7136\u540e\u542f\u52a8 fava-ghost:\n\n```bash\nfava-ghost --repo-url https://github.com/REPO --repo-credentials GITHUB_TOKEN --repo-path PATH_TO_REPO\n```\n\n\u5176\u4e2d PATH_TO_REPO \u662f\u4f60\u7684\u8d26\u672c\u4ed3\u5e93\u7684\u672c\u5730\u8def\u5f84\uff0c\u6bd4\u5982 `~/Documents/Beancount`\u3002\n\n\u5c31\u53ef\u4ee5\u5f00\u59cb\u81ea\u52a8\u540c\u6b65\u8d26\u672c\u6587\u4ef6\u4e86\u3002\u4e00\u65e6\u542f\u52a8\uff0cfava-ghost \u4f1a\u81ea\u52a8\u5f00\u59cb\u505a\u5982\u4e0b\u4e8b\u60c5:\n\n1. clone \u4f60\u7684\u8d26\u672c\u4ed3\u5e93\u5230 PATH_TO_REPO\n2. \u5728\u8d26\u672c\u4ed3\u5e93\u4e0b\u6267\u884c pip \u5b89\u88c5\u6240\u9700\u4f9d\u8d56\n3. \u542f\u52a8 fava \u670d\u52a1\n4. \u6bcf\u9694 10 \u79d2\u5c1d\u8bd5\u8fdb\u884c\u540c\u6b65\u672c\u5730\u8d26\u672c\u548c\u4ee3\u7801\u4ed3\u5e93\n\n# \u540c\u6b65\u7b56\u7565\n\n\u5bf9\u4e8e\u4e0d\u540c\u7684\u60c5\u51b5\uff0cfava-ghost \u4f1a\u91c7\u53d6\u4e0d\u540c\u7684\u540c\u6b65\u7b56\u7565\uff1a\n\n1. \u8fdc\u7a0b\u6709\u66f4\u65b0\uff0c\u672c\u5730\u6ca1\u6709\u66f4\u65b0\uff1a\u81ea\u52a8 pull\n2. \u8fdc\u7a0b\u6ca1\u6709\u66f4\u65b0\uff0c\u672c\u5730\u6709\u66f4\u65b0\uff1a\u81ea\u52a8 push\n3. \u8fdc\u7a0b\u548c\u672c\u5730\u90fd\u6709\u66f4\u65b0\uff1a\u6267\u884c merge\uff0c\u5982\u679c\u6ca1\u6709\u51b2\u7a81\uff0c\u5219\u81ea\u52a8 push\u3002\u5982\u679c\u6709\u51b2\u7a81\uff0c\u5219\u9700\u8981\u7528\u6237\u624b\u52a8\u7f16\u8f91\u6587\u4ef6\u5230\u6587\u4ef6\u4e2d\u4e0d\u5b58\u5728\u51b2\u7a81\u6807\u8bb0\u540e\uff0c\u81ea\u52a8 push\n\n# docker\n\nfava-ghost \u4e5f\u53ef\u4ee5\u901a\u8fc7 docker \u8fd0\u884c\u3002\u955c\u50cf\u662f `e7h4n/fava-ghost`\u3002\u4f60\u53ef\u4ee5\u901a\u8fc7\u5982\u4e0b\u547d\u4ee4\u8fd0\u884c\uff1a\n\n```bash\ndocker run e7h4n/fava-ghost -d -p 5000:5000 --repo-url REPO_URL --repo-credentials GITHUB_TOKEN\n```\n\n\u901a\u8fc7 docker\uff0c\u4f60\u53ef\u4ee5\u5728\u4efb\u610f\u4e00\u4e2a\u73af\u5883\u4e0b\u5feb\u901f\u542f\u52a8 fava \u670d\u52a1\u6765\u6258\u7ba1\u4f60\u7684 beancount \u8d26\u672c\uff0c\u65e0\u9700\u89e3\u51b3\u73af\u5883\u95ee\u9898\u3002\n",
"bugtrack_url": null,
"license": "",
"summary": "A daemon for fava server and git repo sync",
"version": "0.1.13",
"project_urls": {
"Bug Reports": "https://github.com/e7h4n/fava-ghost/issues",
"Homepage": "https://github.com/e7h4n/fava-ghost",
"Source": "https://github.com/e7h4n/fava-ghost/"
},
"split_keywords": [
"beancount",
"fava",
"daemon",
"git sync"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "0b10e10a3368f256ceae58cea7c3cd8c69c77a63bcd73b5f0fb35ac70926e03e",
"md5": "b7e0a1443a26655b1458782a144e50d4",
"sha256": "17ec763b35b688e22de35fd396411681a8b25838a644cdf16d0170ba2e3c1481"
},
"downloads": -1,
"filename": "fava_ghost-0.1.13-py3-none-any.whl",
"has_sig": false,
"md5_digest": "b7e0a1443a26655b1458782a144e50d4",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.6, <4",
"size": 5615,
"upload_time": "2024-03-17T11:18:55",
"upload_time_iso_8601": "2024-03-17T11:18:55.210147Z",
"url": "https://files.pythonhosted.org/packages/0b/10/e10a3368f256ceae58cea7c3cd8c69c77a63bcd73b5f0fb35ac70926e03e/fava_ghost-0.1.13-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "d770ae83e4fdd867298147a5a252ed292f3e779e1f29b11d6f1b5f4d4542ceb7",
"md5": "700df63cd5b823abb918394ac9d04fe7",
"sha256": "de9474161804ede7b63a45802759ae741b0ac668f6a031db1ed79a4c2ff44ab5"
},
"downloads": -1,
"filename": "fava-ghost-0.1.13.tar.gz",
"has_sig": false,
"md5_digest": "700df63cd5b823abb918394ac9d04fe7",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.6, <4",
"size": 5236,
"upload_time": "2024-03-17T11:18:56",
"upload_time_iso_8601": "2024-03-17T11:18:56.920067Z",
"url": "https://files.pythonhosted.org/packages/d7/70/ae83e4fdd867298147a5a252ed292f3e779e1f29b11d6f1b5f4d4542ceb7/fava-ghost-0.1.13.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-03-17 11:18:56",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "e7h4n",
"github_project": "fava-ghost",
"travis_ci": false,
"coveralls": true,
"github_actions": true,
"lcname": "fava-ghost"
}