bormail 0.3.3__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.
- bormail-0.3.3/LICENSE +21 -0
- bormail-0.3.3/PKG-INFO +330 -0
- bormail-0.3.3/README.md +264 -0
- bormail-0.3.3/bor/__init__.py +9 -0
- bormail-0.3.3/bor/app.py +539 -0
- bormail-0.3.3/bor/config.py +273 -0
- bormail-0.3.3/bor/mu.py +1051 -0
- bormail-0.3.3/bor/tabs/__init__.py +1 -0
- bormail-0.3.3/bor/tabs/attachments.py +679 -0
- bormail-0.3.3/bor/tabs/base.py +65 -0
- bormail-0.3.3/bor/tabs/compose.py +1414 -0
- bormail-0.3.3/bor/tabs/message.py +784 -0
- bormail-0.3.3/bor/tabs/message_index.py +1016 -0
- bormail-0.3.3/bor/tabs/sync.py +216 -0
- bormail-0.3.3/bormail.egg-info/PKG-INFO +330 -0
- bormail-0.3.3/bormail.egg-info/SOURCES.txt +24 -0
- bormail-0.3.3/bormail.egg-info/dependency_links.txt +1 -0
- bormail-0.3.3/bormail.egg-info/entry_points.txt +2 -0
- bormail-0.3.3/bormail.egg-info/requires.txt +25 -0
- bormail-0.3.3/bormail.egg-info/top_level.txt +1 -0
- bormail-0.3.3/pyproject.toml +87 -0
- bormail-0.3.3/setup.cfg +4 -0
- bormail-0.3.3/tests/test_app_integration.py +412 -0
- bormail-0.3.3/tests/test_compose.py +197 -0
- bormail-0.3.3/tests/test_config.py +99 -0
- bormail-0.3.3/tests/test_mu.py +230 -0
bormail-0.3.3/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Bor Development Team
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
bormail-0.3.3/PKG-INFO
ADDED
|
@@ -0,0 +1,330 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: bormail
|
|
3
|
+
Version: 0.3.3
|
|
4
|
+
Summary: Terminal-based email reader using mu and textual
|
|
5
|
+
Author: Bor Development Team
|
|
6
|
+
License: MIT License
|
|
7
|
+
|
|
8
|
+
Copyright (c) 2026 Bor Development Team
|
|
9
|
+
|
|
10
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
in the Software without restriction, including without limitation the rights
|
|
13
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
furnished to do so, subject to the following conditions:
|
|
16
|
+
|
|
17
|
+
The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
copies or substantial portions of the Software.
|
|
19
|
+
|
|
20
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
SOFTWARE.
|
|
27
|
+
|
|
28
|
+
Project-URL: Homepage, https://github.com/slosar/bor
|
|
29
|
+
Project-URL: Documentation, https://github.com/slosar/bor#readme
|
|
30
|
+
Project-URL: Repository, https://github.com/slosar/bor
|
|
31
|
+
Project-URL: Issues, https://github.com/slosar/bor/issues
|
|
32
|
+
Keywords: email,terminal,tui,mu,maildir
|
|
33
|
+
Classifier: Development Status :: 3 - Alpha
|
|
34
|
+
Classifier: Environment :: Console
|
|
35
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
36
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
37
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
38
|
+
Classifier: Operating System :: MacOS
|
|
39
|
+
Classifier: Programming Language :: Python :: 3
|
|
40
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
41
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
42
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
43
|
+
Classifier: Topic :: Communications :: Email :: Email Clients (MUA)
|
|
44
|
+
Requires-Python: >=3.10
|
|
45
|
+
Description-Content-Type: text/markdown
|
|
46
|
+
License-File: LICENSE
|
|
47
|
+
Requires-Dist: textual>=0.40.0
|
|
48
|
+
Requires-Dist: tomli>=2.0.0; python_version < "3.11"
|
|
49
|
+
Requires-Dist: pyperclip>=1.8.0
|
|
50
|
+
Provides-Extra: dev
|
|
51
|
+
Requires-Dist: pytest>=7.0.0; extra == "dev"
|
|
52
|
+
Requires-Dist: pytest-asyncio>=0.21.0; extra == "dev"
|
|
53
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
54
|
+
Requires-Dist: mypy>=1.0.0; extra == "dev"
|
|
55
|
+
Provides-Extra: html
|
|
56
|
+
Requires-Dist: html2text>=2020.1.16; extra == "html"
|
|
57
|
+
Provides-Extra: images
|
|
58
|
+
Requires-Dist: Pillow>=9.0.0; extra == "images"
|
|
59
|
+
Provides-Extra: keyring
|
|
60
|
+
Requires-Dist: keyring>=23.0.0; extra == "keyring"
|
|
61
|
+
Provides-Extra: all
|
|
62
|
+
Requires-Dist: html2text>=2020.1.16; extra == "all"
|
|
63
|
+
Requires-Dist: keyring>=23.0.0; extra == "all"
|
|
64
|
+
Requires-Dist: Pillow>=9.0.0; extra == "all"
|
|
65
|
+
Dynamic: license-file
|
|
66
|
+
|
|
67
|
+
# Bor - Terminal Email Reader
|
|
68
|
+
|
|
69
|
+
[](https://github.com/slosar/bor/actions/workflows/tests.yml) [](https://pypi.org/project/bormail/)
|
|
70
|
+
|
|
71
|
+
Bor means pine in Slovenian. Bor is also an email reader inspired by [pine](https://en.wikipedia.org/wiki/Pine_%28email_client%29).
|
|
72
|
+
|
|
73
|
+
I used to use pine and later its derivatives (alpine, realpine) until it became unsustainable. I switched to mu4e over a decade ago, but while I liked many things, it was never quite perfect.
|
|
74
|
+
|
|
75
|
+
A few years ago I switched away from emacs to VSCode and with the advent of AI coding I finally bite the bullet and made my very own mail client that works exactly the way I want it. Think of bor as pine dragged (by its feet) into 2025.
|
|
76
|
+
|
|
77
|
+
Bor uses [mu](https://djcbsoftware.nl/code/mu/) for email access under the hoold and [Textual](https://textual.textualize.io/) for the user interface.
|
|
78
|
+
|
|
79
|
+
## Some screenshots
|
|
80
|
+
|
|
81
|
+
### Message index
|
|
82
|
+

|
|
83
|
+
### Tabbed message reading
|
|
84
|
+

|
|
85
|
+
### In-terminal preview using kitty terminal protocol
|
|
86
|
+

|
|
87
|
+
|
|
88
|
+
## Features
|
|
89
|
+
|
|
90
|
+
- **Fast email searching** using mu's powerful query language
|
|
91
|
+
- **Threaded message view** with visual indentation
|
|
92
|
+
- **Message composition** with address autocompletion and Ctrl-C/V/X handling global clipboard even in terminal
|
|
93
|
+
- **Attachment handling** with preview (using kitty terminal graphics capabilities)
|
|
94
|
+
- **Keyboard-driven interface**
|
|
95
|
+
- **Tab-based workflow**
|
|
96
|
+
- **Configurable** via TOML configuration file
|
|
97
|
+
- **HTML email support** via html2text rendering
|
|
98
|
+
|
|
99
|
+
## Requirements
|
|
100
|
+
|
|
101
|
+
- Python 3.10+
|
|
102
|
+
- [mu](https://djcbsoftware.nl/code/mu/) (maildir indexer)
|
|
103
|
+
- [Textual](https://textual.textualize.io/) library
|
|
104
|
+
- Optional: html2text for HTML email rendering
|
|
105
|
+
- Optional: kitty terminal for image preview
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
## Known issues
|
|
109
|
+
|
|
110
|
+
- no support for folders. You can mu search with maildir:/folder, but all archived messages go to the archived folder. This is how my work-flow works. Feel free to add and make pull request.
|
|
111
|
+
- Clicking with mouse on the link does not work. For emails with one or two links, 'O' shortcut is preferrable, but for complex long messages, clicking on the link would be better.
|
|
112
|
+
|
|
113
|
+
## Installation
|
|
114
|
+
|
|
115
|
+
### From PyPI
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
pip install bormail
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### From source
|
|
122
|
+
|
|
123
|
+
```bash
|
|
124
|
+
# Clone the repository
|
|
125
|
+
git clone https://github.com/your-repo/bor.git
|
|
126
|
+
cd bor
|
|
127
|
+
|
|
128
|
+
# Install with pip
|
|
129
|
+
pip install -e .
|
|
130
|
+
|
|
131
|
+
# Or install dependencies manually
|
|
132
|
+
pip install textual tomli html2text
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Dependencies
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Install mu on Debian/Ubuntu
|
|
139
|
+
sudo apt install maildir-utils
|
|
140
|
+
|
|
141
|
+
# Install mu on Arch Linux
|
|
142
|
+
sudo pacman -S mu
|
|
143
|
+
|
|
144
|
+
# Install mu on macOS
|
|
145
|
+
brew install mu
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Release
|
|
149
|
+
|
|
150
|
+
1. Update the version in `pyproject.toml`.
|
|
151
|
+
2. Create a git tag like `v0.1.1` and publish a GitHub Release.
|
|
152
|
+
3. The Build workflow will upload the sdist and wheel to PyPI.
|
|
153
|
+
- Configure PyPI Trusted Publishing for `slosar/bor` before the first release.
|
|
154
|
+
|
|
155
|
+
## Configuration
|
|
156
|
+
|
|
157
|
+
Copy the example configuration file and customize it:
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
cp bor.conf.example ~/.config/bor.conf
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Edit `~/.config/bor.conf` to configure:
|
|
164
|
+
- SMTP server settings
|
|
165
|
+
- Maildir folder paths
|
|
166
|
+
- Display preferences
|
|
167
|
+
- Color scheme
|
|
168
|
+
- Synchronization command
|
|
169
|
+
- Email and text aliases
|
|
170
|
+
|
|
171
|
+
See the [configuration documentation](documentation/configuration.md) for details.
|
|
172
|
+
|
|
173
|
+
## Usage
|
|
174
|
+
|
|
175
|
+
Start Bor:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
python -m bor.app
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Or if installed:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
bor
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
## Keyboard Shortcuts
|
|
188
|
+
|
|
189
|
+
### Global
|
|
190
|
+
|
|
191
|
+
| Key | Action |
|
|
192
|
+
|-----|--------|
|
|
193
|
+
| Alt+0 | Message Index tab |
|
|
194
|
+
| Alt+1-9 | Switch to tab |
|
|
195
|
+
| Ctrl+Q | Quit |
|
|
196
|
+
|
|
197
|
+
### Message Index
|
|
198
|
+
|
|
199
|
+
| Key | Action |
|
|
200
|
+
|-----|--------|
|
|
201
|
+
| ↑/↓ or N/P | Navigate messages |
|
|
202
|
+
| Enter | Open message |
|
|
203
|
+
| R | Reply |
|
|
204
|
+
| F | Forward |
|
|
205
|
+
| C | Compose new |
|
|
206
|
+
| S | Search (mu query) |
|
|
207
|
+
| I | Show Inbox |
|
|
208
|
+
| O | Show Archive |
|
|
209
|
+
| U | Show Drafts |
|
|
210
|
+
| M | Mark message |
|
|
211
|
+
| X | Archive message(s) |
|
|
212
|
+
| A | Apply flag |
|
|
213
|
+
| D | Delete message(s) |
|
|
214
|
+
| E | Edit draft |
|
|
215
|
+
| T | Toggle threading |
|
|
216
|
+
| Ctrl+T | Show thread |
|
|
217
|
+
| L | Sync |
|
|
218
|
+
| Z | Undo move |
|
|
219
|
+
| Ctrl+R | Refresh index |
|
|
220
|
+
|
|
221
|
+
### Message View
|
|
222
|
+
|
|
223
|
+
| Key | Action |
|
|
224
|
+
|-----|--------|
|
|
225
|
+
| Space/PgDn | Scroll down |
|
|
226
|
+
| < | Return to index (keep tab open) |
|
|
227
|
+
| Q | Close tab and return |
|
|
228
|
+
| N/P | Next/Previous message |
|
|
229
|
+
| R | Reply |
|
|
230
|
+
| F | Forward |
|
|
231
|
+
| C | Compose new |
|
|
232
|
+
| M | Mark/unmark message and advance |
|
|
233
|
+
| X | Archive |
|
|
234
|
+
| D | Delete |
|
|
235
|
+
| A | Apply flag |
|
|
236
|
+
| O | Open URL (if multiple, pick [1-9]) |
|
|
237
|
+
| Z | View attachments |
|
|
238
|
+
| Ctrl+R | Toggle full headers |
|
|
239
|
+
|
|
240
|
+
### Compose
|
|
241
|
+
|
|
242
|
+
| Key | Action |
|
|
243
|
+
|-----|--------|
|
|
244
|
+
| Tab | Autocomplete address/text |
|
|
245
|
+
| Ctrl+L L | Send message |
|
|
246
|
+
| Ctrl+L D | Save draft |
|
|
247
|
+
| Ctrl+L X | Cancel |
|
|
248
|
+
| Ctrl+I | Insert file |
|
|
249
|
+
| Ctrl+A | Attach file |
|
|
250
|
+
|
|
251
|
+
### Attachments
|
|
252
|
+
|
|
253
|
+
| Key | Action |
|
|
254
|
+
|-----|--------|
|
|
255
|
+
| 1-9 | Select attachment |
|
|
256
|
+
| Enter | Open with system viewer |
|
|
257
|
+
| S | Save attachment |
|
|
258
|
+
| Shift+S | Save all |
|
|
259
|
+
| Q or Esc | Close and return to message view |
|
|
260
|
+
| < | Return to index (keep tab open) |
|
|
261
|
+
|
|
262
|
+
**URL opener limitation**
|
|
263
|
+
|
|
264
|
+
The URL picker shows and opens the first 9 URLs. If a message has more than 9 URLs, it is easier to copy/paste the link or use terminal link clicking instead.
|
|
265
|
+
|
|
266
|
+
## Search Queries
|
|
267
|
+
|
|
268
|
+
Bor uses mu's query language. Examples:
|
|
269
|
+
|
|
270
|
+
```
|
|
271
|
+
# Search in inbox
|
|
272
|
+
maildir:/INBOX
|
|
273
|
+
|
|
274
|
+
# Unread messages
|
|
275
|
+
flag:unread
|
|
276
|
+
|
|
277
|
+
# From a specific sender
|
|
278
|
+
from:john@example.com
|
|
279
|
+
|
|
280
|
+
# Subject contains word
|
|
281
|
+
subject:meeting
|
|
282
|
+
|
|
283
|
+
# Date range
|
|
284
|
+
date:1w..now
|
|
285
|
+
|
|
286
|
+
# Combine queries
|
|
287
|
+
from:john subject:meeting flag:unread
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
## License
|
|
291
|
+
|
|
292
|
+
MIT. See [LICENSE](LICENSE).
|
|
293
|
+
|
|
294
|
+
See the [mu query documentation](https://djcbsoftware.nl/code/mu/mu4e/Queries.html) for more.
|
|
295
|
+
|
|
296
|
+
## Development
|
|
297
|
+
|
|
298
|
+
### Project Structure
|
|
299
|
+
|
|
300
|
+
```
|
|
301
|
+
bor/
|
|
302
|
+
├── __init__.py # Package init
|
|
303
|
+
├── app.py # Main Textual application
|
|
304
|
+
├── config.py # Configuration handling
|
|
305
|
+
├── mu.py # Mu interface
|
|
306
|
+
└── tabs/
|
|
307
|
+
├── __init__.py
|
|
308
|
+
├── base.py # Base tab class
|
|
309
|
+
├── message_index.py
|
|
310
|
+
├── message.py
|
|
311
|
+
├── compose.py
|
|
312
|
+
├── attachments.py
|
|
313
|
+
└── sync.py
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
### Running tests
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
pytest tests/
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
## License
|
|
323
|
+
|
|
324
|
+
MIT License - see LICENSE file for details.
|
|
325
|
+
|
|
326
|
+
## Credits
|
|
327
|
+
|
|
328
|
+
- [mu/mu4e](https://djcbsoftware.nl/code/mu/) - Email indexing and searching
|
|
329
|
+
- [Textual](https://textual.textualize.io/) - TUI framework
|
|
330
|
+
- Inspired by traditional email clients like pine, mutt, and mu4e
|
bormail-0.3.3/README.md
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
# Bor - Terminal Email Reader
|
|
2
|
+
|
|
3
|
+
[](https://github.com/slosar/bor/actions/workflows/tests.yml) [](https://pypi.org/project/bormail/)
|
|
4
|
+
|
|
5
|
+
Bor means pine in Slovenian. Bor is also an email reader inspired by [pine](https://en.wikipedia.org/wiki/Pine_%28email_client%29).
|
|
6
|
+
|
|
7
|
+
I used to use pine and later its derivatives (alpine, realpine) until it became unsustainable. I switched to mu4e over a decade ago, but while I liked many things, it was never quite perfect.
|
|
8
|
+
|
|
9
|
+
A few years ago I switched away from emacs to VSCode and with the advent of AI coding I finally bite the bullet and made my very own mail client that works exactly the way I want it. Think of bor as pine dragged (by its feet) into 2025.
|
|
10
|
+
|
|
11
|
+
Bor uses [mu](https://djcbsoftware.nl/code/mu/) for email access under the hoold and [Textual](https://textual.textualize.io/) for the user interface.
|
|
12
|
+
|
|
13
|
+
## Some screenshots
|
|
14
|
+
|
|
15
|
+
### Message index
|
|
16
|
+

|
|
17
|
+
### Tabbed message reading
|
|
18
|
+

|
|
19
|
+
### In-terminal preview using kitty terminal protocol
|
|
20
|
+

|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
- **Fast email searching** using mu's powerful query language
|
|
25
|
+
- **Threaded message view** with visual indentation
|
|
26
|
+
- **Message composition** with address autocompletion and Ctrl-C/V/X handling global clipboard even in terminal
|
|
27
|
+
- **Attachment handling** with preview (using kitty terminal graphics capabilities)
|
|
28
|
+
- **Keyboard-driven interface**
|
|
29
|
+
- **Tab-based workflow**
|
|
30
|
+
- **Configurable** via TOML configuration file
|
|
31
|
+
- **HTML email support** via html2text rendering
|
|
32
|
+
|
|
33
|
+
## Requirements
|
|
34
|
+
|
|
35
|
+
- Python 3.10+
|
|
36
|
+
- [mu](https://djcbsoftware.nl/code/mu/) (maildir indexer)
|
|
37
|
+
- [Textual](https://textual.textualize.io/) library
|
|
38
|
+
- Optional: html2text for HTML email rendering
|
|
39
|
+
- Optional: kitty terminal for image preview
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
## Known issues
|
|
43
|
+
|
|
44
|
+
- no support for folders. You can mu search with maildir:/folder, but all archived messages go to the archived folder. This is how my work-flow works. Feel free to add and make pull request.
|
|
45
|
+
- Clicking with mouse on the link does not work. For emails with one or two links, 'O' shortcut is preferrable, but for complex long messages, clicking on the link would be better.
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
### From PyPI
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pip install bormail
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### From source
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Clone the repository
|
|
59
|
+
git clone https://github.com/your-repo/bor.git
|
|
60
|
+
cd bor
|
|
61
|
+
|
|
62
|
+
# Install with pip
|
|
63
|
+
pip install -e .
|
|
64
|
+
|
|
65
|
+
# Or install dependencies manually
|
|
66
|
+
pip install textual tomli html2text
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Dependencies
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
# Install mu on Debian/Ubuntu
|
|
73
|
+
sudo apt install maildir-utils
|
|
74
|
+
|
|
75
|
+
# Install mu on Arch Linux
|
|
76
|
+
sudo pacman -S mu
|
|
77
|
+
|
|
78
|
+
# Install mu on macOS
|
|
79
|
+
brew install mu
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Release
|
|
83
|
+
|
|
84
|
+
1. Update the version in `pyproject.toml`.
|
|
85
|
+
2. Create a git tag like `v0.1.1` and publish a GitHub Release.
|
|
86
|
+
3. The Build workflow will upload the sdist and wheel to PyPI.
|
|
87
|
+
- Configure PyPI Trusted Publishing for `slosar/bor` before the first release.
|
|
88
|
+
|
|
89
|
+
## Configuration
|
|
90
|
+
|
|
91
|
+
Copy the example configuration file and customize it:
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
cp bor.conf.example ~/.config/bor.conf
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Edit `~/.config/bor.conf` to configure:
|
|
98
|
+
- SMTP server settings
|
|
99
|
+
- Maildir folder paths
|
|
100
|
+
- Display preferences
|
|
101
|
+
- Color scheme
|
|
102
|
+
- Synchronization command
|
|
103
|
+
- Email and text aliases
|
|
104
|
+
|
|
105
|
+
See the [configuration documentation](documentation/configuration.md) for details.
|
|
106
|
+
|
|
107
|
+
## Usage
|
|
108
|
+
|
|
109
|
+
Start Bor:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
python -m bor.app
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Or if installed:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
bor
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
## Keyboard Shortcuts
|
|
122
|
+
|
|
123
|
+
### Global
|
|
124
|
+
|
|
125
|
+
| Key | Action |
|
|
126
|
+
|-----|--------|
|
|
127
|
+
| Alt+0 | Message Index tab |
|
|
128
|
+
| Alt+1-9 | Switch to tab |
|
|
129
|
+
| Ctrl+Q | Quit |
|
|
130
|
+
|
|
131
|
+
### Message Index
|
|
132
|
+
|
|
133
|
+
| Key | Action |
|
|
134
|
+
|-----|--------|
|
|
135
|
+
| ↑/↓ or N/P | Navigate messages |
|
|
136
|
+
| Enter | Open message |
|
|
137
|
+
| R | Reply |
|
|
138
|
+
| F | Forward |
|
|
139
|
+
| C | Compose new |
|
|
140
|
+
| S | Search (mu query) |
|
|
141
|
+
| I | Show Inbox |
|
|
142
|
+
| O | Show Archive |
|
|
143
|
+
| U | Show Drafts |
|
|
144
|
+
| M | Mark message |
|
|
145
|
+
| X | Archive message(s) |
|
|
146
|
+
| A | Apply flag |
|
|
147
|
+
| D | Delete message(s) |
|
|
148
|
+
| E | Edit draft |
|
|
149
|
+
| T | Toggle threading |
|
|
150
|
+
| Ctrl+T | Show thread |
|
|
151
|
+
| L | Sync |
|
|
152
|
+
| Z | Undo move |
|
|
153
|
+
| Ctrl+R | Refresh index |
|
|
154
|
+
|
|
155
|
+
### Message View
|
|
156
|
+
|
|
157
|
+
| Key | Action |
|
|
158
|
+
|-----|--------|
|
|
159
|
+
| Space/PgDn | Scroll down |
|
|
160
|
+
| < | Return to index (keep tab open) |
|
|
161
|
+
| Q | Close tab and return |
|
|
162
|
+
| N/P | Next/Previous message |
|
|
163
|
+
| R | Reply |
|
|
164
|
+
| F | Forward |
|
|
165
|
+
| C | Compose new |
|
|
166
|
+
| M | Mark/unmark message and advance |
|
|
167
|
+
| X | Archive |
|
|
168
|
+
| D | Delete |
|
|
169
|
+
| A | Apply flag |
|
|
170
|
+
| O | Open URL (if multiple, pick [1-9]) |
|
|
171
|
+
| Z | View attachments |
|
|
172
|
+
| Ctrl+R | Toggle full headers |
|
|
173
|
+
|
|
174
|
+
### Compose
|
|
175
|
+
|
|
176
|
+
| Key | Action |
|
|
177
|
+
|-----|--------|
|
|
178
|
+
| Tab | Autocomplete address/text |
|
|
179
|
+
| Ctrl+L L | Send message |
|
|
180
|
+
| Ctrl+L D | Save draft |
|
|
181
|
+
| Ctrl+L X | Cancel |
|
|
182
|
+
| Ctrl+I | Insert file |
|
|
183
|
+
| Ctrl+A | Attach file |
|
|
184
|
+
|
|
185
|
+
### Attachments
|
|
186
|
+
|
|
187
|
+
| Key | Action |
|
|
188
|
+
|-----|--------|
|
|
189
|
+
| 1-9 | Select attachment |
|
|
190
|
+
| Enter | Open with system viewer |
|
|
191
|
+
| S | Save attachment |
|
|
192
|
+
| Shift+S | Save all |
|
|
193
|
+
| Q or Esc | Close and return to message view |
|
|
194
|
+
| < | Return to index (keep tab open) |
|
|
195
|
+
|
|
196
|
+
**URL opener limitation**
|
|
197
|
+
|
|
198
|
+
The URL picker shows and opens the first 9 URLs. If a message has more than 9 URLs, it is easier to copy/paste the link or use terminal link clicking instead.
|
|
199
|
+
|
|
200
|
+
## Search Queries
|
|
201
|
+
|
|
202
|
+
Bor uses mu's query language. Examples:
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
# Search in inbox
|
|
206
|
+
maildir:/INBOX
|
|
207
|
+
|
|
208
|
+
# Unread messages
|
|
209
|
+
flag:unread
|
|
210
|
+
|
|
211
|
+
# From a specific sender
|
|
212
|
+
from:john@example.com
|
|
213
|
+
|
|
214
|
+
# Subject contains word
|
|
215
|
+
subject:meeting
|
|
216
|
+
|
|
217
|
+
# Date range
|
|
218
|
+
date:1w..now
|
|
219
|
+
|
|
220
|
+
# Combine queries
|
|
221
|
+
from:john subject:meeting flag:unread
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## License
|
|
225
|
+
|
|
226
|
+
MIT. See [LICENSE](LICENSE).
|
|
227
|
+
|
|
228
|
+
See the [mu query documentation](https://djcbsoftware.nl/code/mu/mu4e/Queries.html) for more.
|
|
229
|
+
|
|
230
|
+
## Development
|
|
231
|
+
|
|
232
|
+
### Project Structure
|
|
233
|
+
|
|
234
|
+
```
|
|
235
|
+
bor/
|
|
236
|
+
├── __init__.py # Package init
|
|
237
|
+
├── app.py # Main Textual application
|
|
238
|
+
├── config.py # Configuration handling
|
|
239
|
+
├── mu.py # Mu interface
|
|
240
|
+
└── tabs/
|
|
241
|
+
├── __init__.py
|
|
242
|
+
├── base.py # Base tab class
|
|
243
|
+
├── message_index.py
|
|
244
|
+
├── message.py
|
|
245
|
+
├── compose.py
|
|
246
|
+
├── attachments.py
|
|
247
|
+
└── sync.py
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Running tests
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
pytest tests/
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
## License
|
|
257
|
+
|
|
258
|
+
MIT License - see LICENSE file for details.
|
|
259
|
+
|
|
260
|
+
## Credits
|
|
261
|
+
|
|
262
|
+
- [mu/mu4e](https://djcbsoftware.nl/code/mu/) - Email indexing and searching
|
|
263
|
+
- [Textual](https://textual.textualize.io/) - TUI framework
|
|
264
|
+
- Inspired by traditional email clients like pine, mutt, and mu4e
|