her-sync 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- her_sync-0.3.0/.gitignore +20 -0
- her_sync-0.3.0/PKG-INFO +115 -0
- her_sync-0.3.0/README.md +86 -0
- her_sync-0.3.0/calendar_filters.yaml +7 -0
- her_sync-0.3.0/deploy/DISTRIBUTION.md +56 -0
- her_sync-0.3.0/deploy/calendar.example.yml +10 -0
- her_sync-0.3.0/deploy/config.example.yml +2 -0
- her_sync-0.3.0/deploy/crm.example.yml +9 -0
- her_sync-0.3.0/deploy/her@.service +11 -0
- her_sync-0.3.0/deploy/mail.example.yml +9 -0
- her_sync-0.3.0/deploy/profile.example.yml +8 -0
- her_sync-0.3.0/deploy/systemd-install.sh +12 -0
- her_sync-0.3.0/email_filters.yaml +26 -0
- her_sync-0.3.0/pyproject.toml +38 -0
- her_sync-0.3.0/scripts/her-release +9 -0
- her_sync-0.3.0/scripts/release_cli.py +329 -0
- her_sync-0.3.0/skills/receipt-extraction/SKILL.md +67 -0
- her_sync-0.3.0/src/her_sync/__init__.py +3 -0
- her_sync-0.3.0/src/her_sync/__main__.py +3 -0
- her_sync-0.3.0/src/her_sync/apply/__init__.py +8 -0
- her_sync-0.3.0/src/her_sync/apply/cost_centers.py +84 -0
- her_sync-0.3.0/src/her_sync/apply/invoices.py +77 -0
- her_sync-0.3.0/src/her_sync/bde/__init__.py +11 -0
- her_sync-0.3.0/src/her_sync/bde/cashflows.py +150 -0
- her_sync-0.3.0/src/her_sync/bde/cost_centers.py +22 -0
- her_sync-0.3.0/src/her_sync/bde/invoices.py +199 -0
- her_sync-0.3.0/src/her_sync/bde/session.py +124 -0
- her_sync-0.3.0/src/her_sync/cli.py +407 -0
- her_sync-0.3.0/src/her_sync/cli_helpers.py +10 -0
- her_sync-0.3.0/src/her_sync/collectors/__init__.py +10 -0
- her_sync-0.3.0/src/her_sync/collectors/cashflows.py +166 -0
- her_sync-0.3.0/src/her_sync/collectors/invoices.py +70 -0
- her_sync-0.3.0/src/her_sync/collectors/receipts.py +30 -0
- her_sync-0.3.0/src/her_sync/config.py +153 -0
- her_sync-0.3.0/src/her_sync/daemon.py +102 -0
- her_sync-0.3.0/src/her_sync/io/paths.py +69 -0
- her_sync-0.3.0/src/her_sync/io/xlsx.py +51 -0
- her_sync-0.3.0/src/her_sync/migrate.py +252 -0
- her_sync-0.3.0/src/her_sync/plugins/__init__.py +1 -0
- her_sync-0.3.0/src/her_sync/plugins/bde.py +180 -0
- her_sync-0.3.0/src/her_sync/plugins/caldav.py +124 -0
- her_sync-0.3.0/src/her_sync/plugins/email.py +59 -0
- her_sync-0.3.0/src/her_sync/profile.py +275 -0
- her_sync-0.3.0/src/her_sync/secrets.py +92 -0
- her_sync-0.3.0/src/her_sync/sync/__init__.py +3 -0
- her_sync-0.3.0/src/her_sync/sync/caldav_client.py +199 -0
- her_sync-0.3.0/src/her_sync/sync/calendar.py +287 -0
- her_sync-0.3.0/src/her_sync/sync/calendar_filters.py +53 -0
- her_sync-0.3.0/src/her_sync/sync/calendar_priority.py +59 -0
- her_sync-0.3.0/src/her_sync/sync/email.py +498 -0
- her_sync-0.3.0/src/her_sync/sync/email_filters.py +77 -0
- her_sync-0.3.0/src/her_sync/sync/email_watcher.py +151 -0
- her_sync-0.3.0/src/her_sync/sync/gloda_index.py +63 -0
- her_sync-0.3.0/src/her_sync/sync/mbox_reader.py +163 -0
- her_sync-0.3.0/src/her_sync/sync/msf_index.py +279 -0
- her_sync-0.3.0/src/her_sync/sync/sync_lock.py +28 -0
- her_sync-0.3.0/src/her_sync/tools/browser_record.py +76 -0
- her_sync-0.3.0/tests/test_caldav_client.py +56 -0
- her_sync-0.3.0/tests/test_email_sync.py +91 -0
- her_sync-0.3.0/tests/test_mbox_reader.py +39 -0
- her_sync-0.3.0/tests/test_migrate.py +28 -0
- her_sync-0.3.0/tests/test_msf_index.py +60 -0
- her_sync-0.3.0/tests/test_paths.py +36 -0
- her_sync-0.3.0/tests/test_profile.py +50 -0
- her_sync-0.3.0/tests/test_pypi_token.py +45 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.env
|
|
2
|
+
.venv/
|
|
3
|
+
__pycache__/
|
|
4
|
+
*.pyc
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
.ruff_cache/
|
|
7
|
+
*.egg-info/
|
|
8
|
+
dist/
|
|
9
|
+
build/
|
|
10
|
+
share/
|
|
11
|
+
|
|
12
|
+
# Share-Verzeichnis enthält sensible Daten
|
|
13
|
+
share/data/
|
|
14
|
+
share/inbox/
|
|
15
|
+
share/outbox/
|
|
16
|
+
share/complete/
|
|
17
|
+
|
|
18
|
+
# Browser-Session für manuelles Login
|
|
19
|
+
.sessions/
|
|
20
|
+
playwright-state/
|
her_sync-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: her-sync
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Linux-native Sync-Tool für Agent-Share-Filesysteme (BDE, Email, CalDAV)
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Requires-Dist: beautifulsoup4>=4.12
|
|
7
|
+
Requires-Dist: caldav>=1.3
|
|
8
|
+
Requires-Dist: httpx>=0.27
|
|
9
|
+
Requires-Dist: icalendar>=6.0
|
|
10
|
+
Requires-Dist: keyring>=25.0
|
|
11
|
+
Requires-Dist: lxml>=5.0
|
|
12
|
+
Requires-Dist: openpyxl>=3.1
|
|
13
|
+
Requires-Dist: pydantic>=2.0
|
|
14
|
+
Requires-Dist: pyyaml>=6.0
|
|
15
|
+
Requires-Dist: rich>=13.0
|
|
16
|
+
Requires-Dist: typer[all]>=0.12
|
|
17
|
+
Provides-Extra: dev
|
|
18
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
19
|
+
Requires-Dist: playwright>=1.40; extra == 'dev'
|
|
20
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
21
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
22
|
+
Requires-Dist: twine>=5.0; extra == 'dev'
|
|
23
|
+
Provides-Extra: release
|
|
24
|
+
Requires-Dist: build>=1.0; extra == 'release'
|
|
25
|
+
Requires-Dist: twine>=5.0; extra == 'release'
|
|
26
|
+
Provides-Extra: watch
|
|
27
|
+
Requires-Dist: watchdog>=4.0; extra == 'watch'
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# her-sync
|
|
31
|
+
|
|
32
|
+
Linux-native Sync-Tool für Agent-Share-Filesysteme (BDE, Email, CalDAV).
|
|
33
|
+
CLI-Befehl: **`her`**
|
|
34
|
+
|
|
35
|
+
## Installation
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
pipx install "her-sync[watch]"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Aus Git:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pipx install --force "git+https://gitea.example.com/you/her-sync@main#egg=her-sync[watch]"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Entwicklung: `pip install -e ".[watch,dev]"`
|
|
48
|
+
|
|
49
|
+
## Konfiguration
|
|
50
|
+
|
|
51
|
+
`~/.her/`
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
~/.her/
|
|
55
|
+
├── config.yml
|
|
56
|
+
├── profiles/bde-work/
|
|
57
|
+
│ ├── profile.yml # share + watch
|
|
58
|
+
│ ├── crm.yml # bde: { ... }
|
|
59
|
+
│ ├── mail.yml # email: { ... }
|
|
60
|
+
│ ├── calendar.yml # caldav: { ... }
|
|
61
|
+
│ └── local.yml # optional: Overrides (alphabetisch später = gewinnt)
|
|
62
|
+
├── state/bde-work/
|
|
63
|
+
└── share-bde/ # optional — Share kann auch woanders liegen
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Alle `.yml`-Dateien im Profilordner werden **alphabetisch** geladen und deep-gemergt.
|
|
67
|
+
Welches Plugin aktiv ist, ergibt sich **nur aus dem YAML-Key** (`bde:`, `email:`, `caldav:`) —
|
|
68
|
+
der Dateiname spielt keine Rolle. Fehlender Key = Plugin deaktiviert.
|
|
69
|
+
|
|
70
|
+
```yaml
|
|
71
|
+
# local.yml — optional, überschreibt Teile aus calendar.yml o.ä.
|
|
72
|
+
caldav:
|
|
73
|
+
months_past: 6
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
her profile init bde-work
|
|
78
|
+
her profile migrate-env --env-file .env --name bde-work
|
|
79
|
+
her secrets set bde-work/bde-password
|
|
80
|
+
her --profile bde-work status
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## CLI
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
her profile list|show|init|migrate-env|validate
|
|
87
|
+
her secrets set|delete|test
|
|
88
|
+
her daemon run|start|stop|status
|
|
89
|
+
her status
|
|
90
|
+
|
|
91
|
+
her bde collect cashflows
|
|
92
|
+
her bde collect cashflow-history --force
|
|
93
|
+
her bde apply cost-centers --dry-run
|
|
94
|
+
|
|
95
|
+
her email sync
|
|
96
|
+
her caldav ls
|
|
97
|
+
her caldav sync
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Daemon
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
her daemon run --profile bde-work
|
|
104
|
+
./deploy/systemd-install.sh bde-work
|
|
105
|
+
systemctl --user start her@bde-work
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Release (Repo-Checkout)
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
her secrets set release/her-pypi-token # einmalig lokal
|
|
112
|
+
./scripts/her-release release --bump patch --pypi
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Details: [deploy/DISTRIBUTION.md](deploy/DISTRIBUTION.md)
|
her_sync-0.3.0/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# her-sync
|
|
2
|
+
|
|
3
|
+
Linux-native Sync-Tool für Agent-Share-Filesysteme (BDE, Email, CalDAV).
|
|
4
|
+
CLI-Befehl: **`her`**
|
|
5
|
+
|
|
6
|
+
## Installation
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
pipx install "her-sync[watch]"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Aus Git:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pipx install --force "git+https://gitea.example.com/you/her-sync@main#egg=her-sync[watch]"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Entwicklung: `pip install -e ".[watch,dev]"`
|
|
19
|
+
|
|
20
|
+
## Konfiguration
|
|
21
|
+
|
|
22
|
+
`~/.her/`
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
~/.her/
|
|
26
|
+
├── config.yml
|
|
27
|
+
├── profiles/bde-work/
|
|
28
|
+
│ ├── profile.yml # share + watch
|
|
29
|
+
│ ├── crm.yml # bde: { ... }
|
|
30
|
+
│ ├── mail.yml # email: { ... }
|
|
31
|
+
│ ├── calendar.yml # caldav: { ... }
|
|
32
|
+
│ └── local.yml # optional: Overrides (alphabetisch später = gewinnt)
|
|
33
|
+
├── state/bde-work/
|
|
34
|
+
└── share-bde/ # optional — Share kann auch woanders liegen
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Alle `.yml`-Dateien im Profilordner werden **alphabetisch** geladen und deep-gemergt.
|
|
38
|
+
Welches Plugin aktiv ist, ergibt sich **nur aus dem YAML-Key** (`bde:`, `email:`, `caldav:`) —
|
|
39
|
+
der Dateiname spielt keine Rolle. Fehlender Key = Plugin deaktiviert.
|
|
40
|
+
|
|
41
|
+
```yaml
|
|
42
|
+
# local.yml — optional, überschreibt Teile aus calendar.yml o.ä.
|
|
43
|
+
caldav:
|
|
44
|
+
months_past: 6
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
her profile init bde-work
|
|
49
|
+
her profile migrate-env --env-file .env --name bde-work
|
|
50
|
+
her secrets set bde-work/bde-password
|
|
51
|
+
her --profile bde-work status
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## CLI
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
her profile list|show|init|migrate-env|validate
|
|
58
|
+
her secrets set|delete|test
|
|
59
|
+
her daemon run|start|stop|status
|
|
60
|
+
her status
|
|
61
|
+
|
|
62
|
+
her bde collect cashflows
|
|
63
|
+
her bde collect cashflow-history --force
|
|
64
|
+
her bde apply cost-centers --dry-run
|
|
65
|
+
|
|
66
|
+
her email sync
|
|
67
|
+
her caldav ls
|
|
68
|
+
her caldav sync
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Daemon
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
her daemon run --profile bde-work
|
|
75
|
+
./deploy/systemd-install.sh bde-work
|
|
76
|
+
systemctl --user start her@bde-work
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Release (Repo-Checkout)
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
her secrets set release/her-pypi-token # einmalig lokal
|
|
83
|
+
./scripts/her-release release --bump patch --pypi
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Details: [deploy/DISTRIBUTION.md](deploy/DISTRIBUTION.md)
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Distribution
|
|
2
|
+
|
|
3
|
+
Paket: **her-sync** auf PyPI
|
|
4
|
+
CLI: **`her`**
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
pipx install her-sync
|
|
8
|
+
# oder mit Watch-Extra:
|
|
9
|
+
pipx install "her-sync[watch]"
|
|
10
|
+
|
|
11
|
+
# Aus Git:
|
|
12
|
+
pipx install --force "git+https://gitea.example.com/you/her-sync@v0.3.0#egg=her-sync[watch]"
|
|
13
|
+
|
|
14
|
+
# Lokaler Checkout:
|
|
15
|
+
pipx install --force ".[watch]"
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Release
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install -e ".[dev]" # build + twine für Publish
|
|
22
|
+
|
|
23
|
+
# Lokal: Tag + pipx
|
|
24
|
+
./scripts/her-release release --bump patch
|
|
25
|
+
|
|
26
|
+
# Mit PyPI-Upload (Keyring):
|
|
27
|
+
her secrets set release/her-pypi-token
|
|
28
|
+
./scripts/her-release release --bump patch --pypi
|
|
29
|
+
|
|
30
|
+
# Nur Upload (ohne Git-Tag):
|
|
31
|
+
./scripts/her-release publish
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### PyPI-Token
|
|
35
|
+
|
|
36
|
+
| Quelle | Wann |
|
|
37
|
+
|---|---|
|
|
38
|
+
| `HER_PYPI_TOKEN` | CI — bevorzugt |
|
|
39
|
+
| `TWINE_PASSWORD` | CI-Fallback (twine-kompatibel) |
|
|
40
|
+
| Keyring `release/her-pypi-token` | Lokal (Default) |
|
|
41
|
+
| `HER_PYPI_KEYRING` / `--pypi-keyring` | Anderer Keyring-Ref |
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
# Lokal einmalig
|
|
45
|
+
her secrets set release/her-pypi-token
|
|
46
|
+
|
|
47
|
+
# CI (Gitea/GitHub Actions)
|
|
48
|
+
export HER_PYPI_TOKEN=pypi-AgEI...
|
|
49
|
+
./scripts/her-release release --bump patch --pypi --no-pipx
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Keyring-Service bleibt `her-sync` — Release-Refs unter `release/…`, getrennt von Profil-Secrets (`bde-work/…`).
|
|
53
|
+
|
|
54
|
+
## Config
|
|
55
|
+
|
|
56
|
+
`~/.her/` — Keyring-Service: `her-sync`
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
PROFILE="${1:-bde-work}"
|
|
4
|
+
UNIT_DIR="${HOME}/.config/systemd/user"
|
|
5
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
6
|
+
|
|
7
|
+
mkdir -p "$UNIT_DIR"
|
|
8
|
+
cp "${SCRIPT_DIR}/her@.service" "${UNIT_DIR}/"
|
|
9
|
+
systemctl --user daemon-reload
|
|
10
|
+
systemctl --user enable "her@${PROFILE}.service"
|
|
11
|
+
echo "Installiert: her@${PROFILE}"
|
|
12
|
+
echo "Start: systemctl --user start her@${PROFILE}"
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# E-Mail Export-Filter (Betterbird mbox, relativ zu BETTERBIRD_PROFILE)
|
|
2
|
+
# Export nach: share/data/inbox/emails/<name>/<YYYYMMDD_HHMMSS>_<hash>/ (UTC)
|
|
3
|
+
#
|
|
4
|
+
# Pro Filter:
|
|
5
|
+
# folders — mbox-Ordner (mehrere möglich)
|
|
6
|
+
# unread_only — nur ungelesene Mails (X-Mozilla-Status)
|
|
7
|
+
# tags — Betterbird-Tags (X-Mozilla-Keys), mindestens einer muss passen
|
|
8
|
+
# months_past — 0 = kein Datumsfilter; >0 = nur Mails der letzten N Monate
|
|
9
|
+
# trust_gloda_read — bei unread_only: Gloda-Read-Status nutzen wenn MSF noch
|
|
10
|
+
# „ungelesen“ zeigt (Betterbird schreibt .msf verzögert)
|
|
11
|
+
#
|
|
12
|
+
# Beim nächsten Sync werden Exporte gelöscht, die nicht mehr passen.
|
|
13
|
+
|
|
14
|
+
filters:
|
|
15
|
+
- name: unread-inbox
|
|
16
|
+
folders:
|
|
17
|
+
- ImapMail/imap.gmail.com/INBOX
|
|
18
|
+
unread_only: true
|
|
19
|
+
|
|
20
|
+
# - name: rechnungen
|
|
21
|
+
# folders:
|
|
22
|
+
# - ImapMail/imap.gmail.com/[Gmail].sbd/Geschäftlich.sbd/Rechnungen
|
|
23
|
+
# - ImapMail/imap.gmail.com/[Gmail].sbd/Geschäftlich.sbd/Steuer
|
|
24
|
+
# months_past: 3
|
|
25
|
+
# tags:
|
|
26
|
+
# - Steuer
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "her-sync"
|
|
3
|
+
version = "0.3.0"
|
|
4
|
+
description = "Linux-native Sync-Tool für Agent-Share-Filesysteme (BDE, Email, CalDAV)"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"typer[all]>=0.12",
|
|
9
|
+
"httpx>=0.27",
|
|
10
|
+
"beautifulsoup4>=4.12",
|
|
11
|
+
"lxml>=5.0",
|
|
12
|
+
"openpyxl>=3.1",
|
|
13
|
+
"pydantic>=2.0",
|
|
14
|
+
"rich>=13.0",
|
|
15
|
+
"caldav>=1.3",
|
|
16
|
+
"icalendar>=6.0",
|
|
17
|
+
"pyyaml>=6.0",
|
|
18
|
+
"keyring>=25.0",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.optional-dependencies]
|
|
22
|
+
watch = ["watchdog>=4.0"]
|
|
23
|
+
dev = ["pytest>=8.0", "ruff>=0.4", "playwright>=1.40", "build>=1.0", "twine>=5.0"]
|
|
24
|
+
release = ["build>=1.0", "twine>=5.0"]
|
|
25
|
+
|
|
26
|
+
[project.scripts]
|
|
27
|
+
her = "her_sync.cli:app"
|
|
28
|
+
|
|
29
|
+
[build-system]
|
|
30
|
+
requires = ["hatchling"]
|
|
31
|
+
build-backend = "hatchling.build"
|
|
32
|
+
|
|
33
|
+
[tool.hatch.build.targets.wheel]
|
|
34
|
+
packages = ["src/her_sync"]
|
|
35
|
+
|
|
36
|
+
[tool.ruff]
|
|
37
|
+
line-length = 100
|
|
38
|
+
target-version = "py311"
|