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 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
+ [![Tests](https://github.com/slosar/bor/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/slosar/bor/actions/workflows/tests.yml) [![PyPI](https://img.shields.io/pypi/v/bormail.svg)](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
+ ![alt text](./documentation/screenshots/image1.png)
83
+ ### Tabbed message reading
84
+ ![alt text](./documentation/screenshots/image2.png)
85
+ ### In-terminal preview using kitty terminal protocol
86
+ ![alt text](./documentation/screenshots/image3.png)
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
@@ -0,0 +1,264 @@
1
+ # Bor - Terminal Email Reader
2
+
3
+ [![Tests](https://github.com/slosar/bor/actions/workflows/tests.yml/badge.svg?branch=main)](https://github.com/slosar/bor/actions/workflows/tests.yml) [![PyPI](https://img.shields.io/pypi/v/bormail.svg)](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
+ ![alt text](./documentation/screenshots/image1.png)
17
+ ### Tabbed message reading
18
+ ![alt text](./documentation/screenshots/image2.png)
19
+ ### In-terminal preview using kitty terminal protocol
20
+ ![alt text](./documentation/screenshots/image3.png)
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
@@ -0,0 +1,9 @@
1
+ """
2
+ Bor - Terminal Email Reader
3
+
4
+ A terminal-based email client using mu for email access
5
+ and textual for the user interface.
6
+ """
7
+
8
+ __version__ = "0.3.3"
9
+ __author__ = "Bor Development Team"