tmpmail-cli 1.2.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.
- tmpmail_cli-1.2.3/LICENSE +21 -0
- tmpmail_cli-1.2.3/PKG-INFO +205 -0
- tmpmail_cli-1.2.3/README.md +170 -0
- tmpmail_cli-1.2.3/pyproject.toml +47 -0
- tmpmail_cli-1.2.3/setup.cfg +4 -0
- tmpmail_cli-1.2.3/src/tmpmail/__init__.py +9 -0
- tmpmail_cli-1.2.3/src/tmpmail/__main__.py +6 -0
- tmpmail_cli-1.2.3/src/tmpmail/cli.py +504 -0
- tmpmail_cli-1.2.3/src/tmpmail_cli.egg-info/PKG-INFO +205 -0
- tmpmail_cli-1.2.3/src/tmpmail_cli.egg-info/SOURCES.txt +13 -0
- tmpmail_cli-1.2.3/src/tmpmail_cli.egg-info/dependency_links.txt +1 -0
- tmpmail_cli-1.2.3/src/tmpmail_cli.egg-info/entry_points.txt +2 -0
- tmpmail_cli-1.2.3/src/tmpmail_cli.egg-info/requires.txt +7 -0
- tmpmail_cli-1.2.3/src/tmpmail_cli.egg-info/top_level.txt +1 -0
- tmpmail_cli-1.2.3/tests/test_tmpmail.py +26 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2020 Siddharth Dushantha
|
|
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.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tmpmail-cli
|
|
3
|
+
Version: 1.2.3
|
|
4
|
+
Summary: A temporary email right from your terminal
|
|
5
|
+
Author-email: Siddharth Dushantha <siddharth.dushantha@gmail.com>
|
|
6
|
+
Maintainer-email: Siddharth Dushantha <siddharth.dushantha@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/sdushantha/tmpmail
|
|
9
|
+
Project-URL: Repository, https://github.com/sdushantha/tmpmail.git
|
|
10
|
+
Project-URL: BugTracker, https://github.com/sdushantha/tmpmail/issues
|
|
11
|
+
Keywords: email,temporary,cli,1secmail,mailtm
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Communications :: Email
|
|
24
|
+
Classifier: Topic :: Utilities
|
|
25
|
+
Requires-Python: >=3.7
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: requests>=2.25.0
|
|
29
|
+
Requires-Dist: beautifulsoup4>=4.9.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
32
|
+
Requires-Dist: black>=22.0; extra == "dev"
|
|
33
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
<h1 align="center">
|
|
37
|
+
<img src="images/logo.png">
|
|
38
|
+
</h1>
|
|
39
|
+
<p align="center"> A temporary email right from your terminal</p><br>
|
|
40
|
+
|
|
41
|
+
<img src="images/demo.gif" align="right"> `tmpmail` is a command line utility that allows you to create a temporary email address
|
|
42
|
+
and receive emails to the temporary email address. It uses 1secmail's [API](https://www.1secmail.com/api/)
|
|
43
|
+
to receive emails.
|
|
44
|
+
|
|
45
|
+
By default `w3m` is used to render the HTML emails on the terminal.
|
|
46
|
+
But if you prefer another text based web browser or would rather view the email in a GUI web browser such as Firefox, simply
|
|
47
|
+
use the `--browser` argument followed by the command needed to launch the web browser of your choice.
|
|
48
|
+
|
|
49
|
+
<br>
|
|
50
|
+
<br>
|
|
51
|
+
<br>
|
|
52
|
+
|
|
53
|
+
## Dependencies
|
|
54
|
+
|
|
55
|
+
**Python dependencies** (installed automatically with pip):
|
|
56
|
+
- `requests`
|
|
57
|
+
- `beautifulsoup4`
|
|
58
|
+
|
|
59
|
+
**System dependencies** (required for full functionality):
|
|
60
|
+
- `w3m` (or another browser for rendering HTML emails)
|
|
61
|
+
- `xclip` (or another clipboard utility for the `--copy` feature)
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
### Install with pip (Recommended)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Install with pip
|
|
69
|
+
$ pip install tmpmail-cli
|
|
70
|
+
|
|
71
|
+
# Or with pipx for an isolated installation
|
|
72
|
+
$ pipx install tmpmail-cli
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Install from source
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
$ git clone https://github.com/sdushantha/tmpmail.git
|
|
79
|
+
$ cd tmpmail
|
|
80
|
+
$ pip install .
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Install locally (Legacy shell script)
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Download the tmpmail file and make it executable
|
|
87
|
+
$ curl -L "https://raw.githubusercontent.com/sdushantha/tmpmail/master/tmpmail" > tmpmail && chmod +x tmpmail
|
|
88
|
+
|
|
89
|
+
# Then move it somewhere in your $PATH. Here is an example:
|
|
90
|
+
$ mv tmpmail ~/bin/
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### AUR
|
|
94
|
+
`tmpmail` is available on the [AUR](https://aur.archlinux.org/packages/tmpmail-git/), which is currently being maintained by [Benjamin Bädorf](https://github.com/b12f)
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
$ yay -S tmpmail-git
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### [Pacstall](https://github.com/pacstall/pacstall) (Debian/Ubuntu)
|
|
101
|
+
`tmpmail` is available on the [pacstall-programs repository](https://github.com/pacstall/pacstall-programs/blob/master/packages/tmpmail-bin/tmpmail-bin.pacscript), which is being currently being maintained by [wizard-28](https://github.com/wizard-28)
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
$ pacstall -I tmpmail-bin
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Nixpkgs
|
|
108
|
+
`tmpmail` is also available in the [nix package collection (only unstable currently)](https://search.nixos.org/packages?channel=unstable&show=tmpmail&from=0&size=50&sort=relevance&query=tmpmail), which is maintained by [legendofmiracles](https://github.com/legendofmiracles)
|
|
109
|
+
|
|
110
|
+
Either add it to your system packages, install it with nix-env or try it out in a ephemeral nix-shell `nix-shell -p tmpmail`
|
|
111
|
+
|
|
112
|
+
### Docker
|
|
113
|
+
|
|
114
|
+
requirements:
|
|
115
|
+
- [docker](https://www.docker.com/)
|
|
116
|
+
- clone this repo
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
$ docker build -t mail .; # Dockerfile available in source code
|
|
120
|
+
$ docker run -it mail;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Usage
|
|
124
|
+
```console
|
|
125
|
+
$ tmpmail --help
|
|
126
|
+
tmpmail
|
|
127
|
+
tmpmail -h | --version
|
|
128
|
+
tmpmail -g [ADDRESS]
|
|
129
|
+
tmpmail [-t | -b BROWSER] -r | ID
|
|
130
|
+
|
|
131
|
+
When called with no option and no argument, tmpmail lists the messages in
|
|
132
|
+
the inbox and their numeric IDs. When called with one argument, tmpmail
|
|
133
|
+
shows the email message with specified ID.
|
|
134
|
+
|
|
135
|
+
-b, --browser BROWSER
|
|
136
|
+
Specify BROWSER that is used to render the HTML of
|
|
137
|
+
the email (default: w3m)
|
|
138
|
+
--clipboard-cmd COMMAND
|
|
139
|
+
Specify the COMMAND to use for copying the email address to your
|
|
140
|
+
clipboard (default: xclip -selection c)
|
|
141
|
+
-c, --copy
|
|
142
|
+
Copy the email address to your clipboard
|
|
143
|
+
-d, --domains
|
|
144
|
+
Show list of available domains
|
|
145
|
+
-g, --generate [ADDRESS]
|
|
146
|
+
Generate a new email address, either the specified ADDRESS, or
|
|
147
|
+
randomly create one
|
|
148
|
+
-h, --help
|
|
149
|
+
Show help
|
|
150
|
+
-r, --recent
|
|
151
|
+
View the most recent email message
|
|
152
|
+
-t, --text
|
|
153
|
+
View the email as raw text, where all the HTML tags are removed.
|
|
154
|
+
Without this option, HTML is used.
|
|
155
|
+
--version
|
|
156
|
+
Show version
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Examples
|
|
160
|
+
Create random email
|
|
161
|
+
```console
|
|
162
|
+
$ tmpmail --generate
|
|
163
|
+
xoithrjagpx@1secmail.net
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Create custom email
|
|
167
|
+
```console
|
|
168
|
+
$ tmpmail --generate mycustomemail@1secmail.com
|
|
169
|
+
mycustomemail@1secmail.com
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
View the inbox
|
|
173
|
+
```console
|
|
174
|
+
$ tmpmail
|
|
175
|
+
[ Inbox for wdebivbyjor@1secmail.com ]
|
|
176
|
+
|
|
177
|
+
83414443 username@example.com Test Email
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
View the email
|
|
181
|
+
```console
|
|
182
|
+
$ tmpmail 83414443
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
View the most recent email
|
|
186
|
+
```console
|
|
187
|
+
$ tmpmail -r
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
View emails as pure text
|
|
191
|
+
```console
|
|
192
|
+
$ tmpmail -t 83414443
|
|
193
|
+
To: wdebivbyjor@1secmail.com
|
|
194
|
+
From: username@example.com
|
|
195
|
+
Subject: Test Email
|
|
196
|
+
|
|
197
|
+
Hello World
|
|
198
|
+
|
|
199
|
+
[Attachments]
|
|
200
|
+
https://is.gd/aBCdEf [apple.jpg]
|
|
201
|
+
https://is.gd/AbCDeF [ball.jpg]
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Credits
|
|
205
|
+
This script is heavily inspired by Mitch Weaver's [`1secmail`](https://github.com/mitchweaver/bin/blob/master/OLD/1secmail) script
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
<img src="images/logo.png">
|
|
3
|
+
</h1>
|
|
4
|
+
<p align="center"> A temporary email right from your terminal</p><br>
|
|
5
|
+
|
|
6
|
+
<img src="images/demo.gif" align="right"> `tmpmail` is a command line utility that allows you to create a temporary email address
|
|
7
|
+
and receive emails to the temporary email address. It uses 1secmail's [API](https://www.1secmail.com/api/)
|
|
8
|
+
to receive emails.
|
|
9
|
+
|
|
10
|
+
By default `w3m` is used to render the HTML emails on the terminal.
|
|
11
|
+
But if you prefer another text based web browser or would rather view the email in a GUI web browser such as Firefox, simply
|
|
12
|
+
use the `--browser` argument followed by the command needed to launch the web browser of your choice.
|
|
13
|
+
|
|
14
|
+
<br>
|
|
15
|
+
<br>
|
|
16
|
+
<br>
|
|
17
|
+
|
|
18
|
+
## Dependencies
|
|
19
|
+
|
|
20
|
+
**Python dependencies** (installed automatically with pip):
|
|
21
|
+
- `requests`
|
|
22
|
+
- `beautifulsoup4`
|
|
23
|
+
|
|
24
|
+
**System dependencies** (required for full functionality):
|
|
25
|
+
- `w3m` (or another browser for rendering HTML emails)
|
|
26
|
+
- `xclip` (or another clipboard utility for the `--copy` feature)
|
|
27
|
+
|
|
28
|
+
## Installation
|
|
29
|
+
|
|
30
|
+
### Install with pip (Recommended)
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Install with pip
|
|
34
|
+
$ pip install tmpmail-cli
|
|
35
|
+
|
|
36
|
+
# Or with pipx for an isolated installation
|
|
37
|
+
$ pipx install tmpmail-cli
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Install from source
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
$ git clone https://github.com/sdushantha/tmpmail.git
|
|
44
|
+
$ cd tmpmail
|
|
45
|
+
$ pip install .
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Install locally (Legacy shell script)
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Download the tmpmail file and make it executable
|
|
52
|
+
$ curl -L "https://raw.githubusercontent.com/sdushantha/tmpmail/master/tmpmail" > tmpmail && chmod +x tmpmail
|
|
53
|
+
|
|
54
|
+
# Then move it somewhere in your $PATH. Here is an example:
|
|
55
|
+
$ mv tmpmail ~/bin/
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### AUR
|
|
59
|
+
`tmpmail` is available on the [AUR](https://aur.archlinux.org/packages/tmpmail-git/), which is currently being maintained by [Benjamin Bädorf](https://github.com/b12f)
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
$ yay -S tmpmail-git
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
### [Pacstall](https://github.com/pacstall/pacstall) (Debian/Ubuntu)
|
|
66
|
+
`tmpmail` is available on the [pacstall-programs repository](https://github.com/pacstall/pacstall-programs/blob/master/packages/tmpmail-bin/tmpmail-bin.pacscript), which is being currently being maintained by [wizard-28](https://github.com/wizard-28)
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
$ pacstall -I tmpmail-bin
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Nixpkgs
|
|
73
|
+
`tmpmail` is also available in the [nix package collection (only unstable currently)](https://search.nixos.org/packages?channel=unstable&show=tmpmail&from=0&size=50&sort=relevance&query=tmpmail), which is maintained by [legendofmiracles](https://github.com/legendofmiracles)
|
|
74
|
+
|
|
75
|
+
Either add it to your system packages, install it with nix-env or try it out in a ephemeral nix-shell `nix-shell -p tmpmail`
|
|
76
|
+
|
|
77
|
+
### Docker
|
|
78
|
+
|
|
79
|
+
requirements:
|
|
80
|
+
- [docker](https://www.docker.com/)
|
|
81
|
+
- clone this repo
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
$ docker build -t mail .; # Dockerfile available in source code
|
|
85
|
+
$ docker run -it mail;
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Usage
|
|
89
|
+
```console
|
|
90
|
+
$ tmpmail --help
|
|
91
|
+
tmpmail
|
|
92
|
+
tmpmail -h | --version
|
|
93
|
+
tmpmail -g [ADDRESS]
|
|
94
|
+
tmpmail [-t | -b BROWSER] -r | ID
|
|
95
|
+
|
|
96
|
+
When called with no option and no argument, tmpmail lists the messages in
|
|
97
|
+
the inbox and their numeric IDs. When called with one argument, tmpmail
|
|
98
|
+
shows the email message with specified ID.
|
|
99
|
+
|
|
100
|
+
-b, --browser BROWSER
|
|
101
|
+
Specify BROWSER that is used to render the HTML of
|
|
102
|
+
the email (default: w3m)
|
|
103
|
+
--clipboard-cmd COMMAND
|
|
104
|
+
Specify the COMMAND to use for copying the email address to your
|
|
105
|
+
clipboard (default: xclip -selection c)
|
|
106
|
+
-c, --copy
|
|
107
|
+
Copy the email address to your clipboard
|
|
108
|
+
-d, --domains
|
|
109
|
+
Show list of available domains
|
|
110
|
+
-g, --generate [ADDRESS]
|
|
111
|
+
Generate a new email address, either the specified ADDRESS, or
|
|
112
|
+
randomly create one
|
|
113
|
+
-h, --help
|
|
114
|
+
Show help
|
|
115
|
+
-r, --recent
|
|
116
|
+
View the most recent email message
|
|
117
|
+
-t, --text
|
|
118
|
+
View the email as raw text, where all the HTML tags are removed.
|
|
119
|
+
Without this option, HTML is used.
|
|
120
|
+
--version
|
|
121
|
+
Show version
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Examples
|
|
125
|
+
Create random email
|
|
126
|
+
```console
|
|
127
|
+
$ tmpmail --generate
|
|
128
|
+
xoithrjagpx@1secmail.net
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Create custom email
|
|
132
|
+
```console
|
|
133
|
+
$ tmpmail --generate mycustomemail@1secmail.com
|
|
134
|
+
mycustomemail@1secmail.com
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
View the inbox
|
|
138
|
+
```console
|
|
139
|
+
$ tmpmail
|
|
140
|
+
[ Inbox for wdebivbyjor@1secmail.com ]
|
|
141
|
+
|
|
142
|
+
83414443 username@example.com Test Email
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
View the email
|
|
146
|
+
```console
|
|
147
|
+
$ tmpmail 83414443
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
View the most recent email
|
|
151
|
+
```console
|
|
152
|
+
$ tmpmail -r
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
View emails as pure text
|
|
156
|
+
```console
|
|
157
|
+
$ tmpmail -t 83414443
|
|
158
|
+
To: wdebivbyjor@1secmail.com
|
|
159
|
+
From: username@example.com
|
|
160
|
+
Subject: Test Email
|
|
161
|
+
|
|
162
|
+
Hello World
|
|
163
|
+
|
|
164
|
+
[Attachments]
|
|
165
|
+
https://is.gd/aBCdEf [apple.jpg]
|
|
166
|
+
https://is.gd/AbCDeF [ball.jpg]
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Credits
|
|
170
|
+
This script is heavily inspired by Mitch Weaver's [`1secmail`](https://github.com/mitchweaver/bin/blob/master/OLD/1secmail) script
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "tmpmail-cli"
|
|
7
|
+
version = "1.2.3"
|
|
8
|
+
description = "A temporary email right from your terminal"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = "MIT"
|
|
11
|
+
authors = [{name = "Siddharth Dushantha", email = "siddharth.dushantha@gmail.com"}]
|
|
12
|
+
maintainers = [{name = "Siddharth Dushantha", email = "siddharth.dushantha@gmail.com"}]
|
|
13
|
+
keywords = ["email", "temporary", "cli", "1secmail", "mailtm"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Environment :: Console",
|
|
17
|
+
"Intended Audience :: End Users/Desktop",
|
|
18
|
+
"Operating System :: OS Independent",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.7",
|
|
21
|
+
"Programming Language :: Python :: 3.8",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Topic :: Communications :: Email",
|
|
27
|
+
"Topic :: Utilities"
|
|
28
|
+
]
|
|
29
|
+
requires-python = ">=3.7"
|
|
30
|
+
dependencies = [
|
|
31
|
+
"requests>=2.25.0",
|
|
32
|
+
"beautifulsoup4>=4.9.0"
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
dev = ["pytest>=6.0", "black>=22.0", "ruff>=0.1.0"]
|
|
37
|
+
|
|
38
|
+
[project.scripts]
|
|
39
|
+
tmpmail = "tmpmail.cli:main"
|
|
40
|
+
|
|
41
|
+
[project.urls]
|
|
42
|
+
Homepage = "https://github.com/sdushantha/tmpmail"
|
|
43
|
+
Repository = "https://github.com/sdushantha/tmpmail.git"
|
|
44
|
+
BugTracker = "https://github.com/sdushantha/tmpmail/issues"
|
|
45
|
+
|
|
46
|
+
[tool.setuptools.packages.find]
|
|
47
|
+
where = ["src"]
|
|
@@ -0,0 +1,504 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
tmpmail - A temporary email right from your terminal
|
|
4
|
+
|
|
5
|
+
A command line utility that allows you to create a temporary email address
|
|
6
|
+
and receive emails. It uses 1secmail's API to receive emails.
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import argparse
|
|
10
|
+
import os
|
|
11
|
+
import random
|
|
12
|
+
import re
|
|
13
|
+
import string
|
|
14
|
+
import subprocess
|
|
15
|
+
import sys
|
|
16
|
+
import tempfile
|
|
17
|
+
from pathlib import Path
|
|
18
|
+
|
|
19
|
+
import requests
|
|
20
|
+
from bs4 import BeautifulSoup
|
|
21
|
+
|
|
22
|
+
VERSION = "1.2.3"
|
|
23
|
+
API_URL = "https://api.mail.tm/"
|
|
24
|
+
|
|
25
|
+
# Default browser for rendering HTML emails
|
|
26
|
+
DEFAULT_BROWSER = "w3m"
|
|
27
|
+
|
|
28
|
+
# Default command for copying to clipboard
|
|
29
|
+
DEFAULT_CLIPBOARD_CMD = "xclip -selection c"
|
|
30
|
+
|
|
31
|
+
# Headers for API requests
|
|
32
|
+
HEADERS = {
|
|
33
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36",
|
|
34
|
+
"Accept": "application/json, text/plain, */*",
|
|
35
|
+
"Accept-Language": "en-US,en;q=0.9",
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class TmpMail:
|
|
40
|
+
"""Main class for tmpmail functionality."""
|
|
41
|
+
|
|
42
|
+
def __init__(self):
|
|
43
|
+
self.tmpmail_dir = Path(tempfile.gettempdir()) / "tmpmail"
|
|
44
|
+
self.email_file = self.tmpmail_dir / "email_address"
|
|
45
|
+
self.password_file = self.tmpmail_dir / "password"
|
|
46
|
+
self.token_file = self.tmpmail_dir / "token"
|
|
47
|
+
self.html_file = self.tmpmail_dir / "tmpmail.html"
|
|
48
|
+
self.browser = DEFAULT_BROWSER
|
|
49
|
+
self.clipboard_cmd = DEFAULT_CLIPBOARD_CMD
|
|
50
|
+
self.raw_text = False
|
|
51
|
+
self.email_address = None
|
|
52
|
+
self.username = None
|
|
53
|
+
self.domain = None
|
|
54
|
+
self.password = None
|
|
55
|
+
self.token = None
|
|
56
|
+
|
|
57
|
+
# Create tmpmail directory if it doesn't exist
|
|
58
|
+
self.tmpmail_dir.mkdir(parents=True, exist_ok=True)
|
|
59
|
+
|
|
60
|
+
def _get_token(self):
|
|
61
|
+
"""Get or create JWT token for API authentication."""
|
|
62
|
+
if self.token_file.exists() and self.token_file.stat().st_size > 0:
|
|
63
|
+
self.token = self.token_file.read_text().strip()
|
|
64
|
+
return self.token
|
|
65
|
+
|
|
66
|
+
# Need to authenticate
|
|
67
|
+
self.get_email_address()
|
|
68
|
+
self._authenticate()
|
|
69
|
+
return self.token
|
|
70
|
+
|
|
71
|
+
def _authenticate(self):
|
|
72
|
+
"""Authenticate and get JWT token."""
|
|
73
|
+
try:
|
|
74
|
+
response = requests.post(
|
|
75
|
+
f"{API_URL}token",
|
|
76
|
+
json={"address": self.email_address, "password": self.password},
|
|
77
|
+
headers=HEADERS,
|
|
78
|
+
timeout=10,
|
|
79
|
+
)
|
|
80
|
+
response.raise_for_status()
|
|
81
|
+
data = response.json()
|
|
82
|
+
self.token = data.get("token")
|
|
83
|
+
if self.token:
|
|
84
|
+
self.token_file.write_text(self.token)
|
|
85
|
+
except requests.RequestException as e:
|
|
86
|
+
print(f"Error authenticating: {e}", file=sys.stderr)
|
|
87
|
+
sys.exit(1)
|
|
88
|
+
|
|
89
|
+
def get_email_address(self):
|
|
90
|
+
"""Get or generate email address."""
|
|
91
|
+
if not self.email_file.exists() or self.email_file.stat().st_size == 0:
|
|
92
|
+
self.generate_email_address()
|
|
93
|
+
|
|
94
|
+
self.email_address = self.email_file.read_text().strip()
|
|
95
|
+
self.username = self.email_address.split("@")[0]
|
|
96
|
+
self.domain = self.email_address.split("@")[1]
|
|
97
|
+
|
|
98
|
+
# Load password if exists
|
|
99
|
+
if self.password_file.exists():
|
|
100
|
+
self.password = self.password_file.read_text().strip()
|
|
101
|
+
|
|
102
|
+
return self.email_address
|
|
103
|
+
|
|
104
|
+
def get_domains(self):
|
|
105
|
+
"""Get list of available domains from mail.tm API."""
|
|
106
|
+
try:
|
|
107
|
+
response = requests.get(f"{API_URL}domains", headers=HEADERS, timeout=10)
|
|
108
|
+
response.raise_for_status()
|
|
109
|
+
data = response.json()
|
|
110
|
+
domains = [d.get("domain") for d in data.get("hydra:member", [])]
|
|
111
|
+
if not domains:
|
|
112
|
+
print("Error: mail.tm API error for getting domains list", file=sys.stderr)
|
|
113
|
+
sys.exit(1)
|
|
114
|
+
return domains
|
|
115
|
+
except requests.RequestException as e:
|
|
116
|
+
print(f"Error fetching domains: {e}", file=sys.stderr)
|
|
117
|
+
sys.exit(1)
|
|
118
|
+
|
|
119
|
+
def generate_email_address(self, custom_address=None):
|
|
120
|
+
"""Generate a random or custom email address."""
|
|
121
|
+
blacklisted = ["abuse", "webmaster", "contact", "postmaster", "hostmaster", "admin"]
|
|
122
|
+
domains = self.get_domains()
|
|
123
|
+
domain_regex = "|".join(re.escape(d) for d in domains)
|
|
124
|
+
valid_email_regex = re.compile(rf"^[a-z0-9]+@({domain_regex})$")
|
|
125
|
+
blacklisted_regex = re.compile(rf"^({'|'.join(blacklisted)})$")
|
|
126
|
+
|
|
127
|
+
# Generate random password
|
|
128
|
+
self.password = "".join(random.choices(string.ascii_letters + string.digits + "!@#$%", k=16))
|
|
129
|
+
|
|
130
|
+
if custom_address:
|
|
131
|
+
email_address = custom_address
|
|
132
|
+
username = email_address.split("@")[0]
|
|
133
|
+
|
|
134
|
+
if blacklisted_regex.match(username):
|
|
135
|
+
print(
|
|
136
|
+
f"Error: For security reasons, that username cannot be used. "
|
|
137
|
+
f"Blacklisted: {', '.join(blacklisted)}",
|
|
138
|
+
file=sys.stderr,
|
|
139
|
+
)
|
|
140
|
+
sys.exit(1)
|
|
141
|
+
|
|
142
|
+
if not valid_email_regex.match(email_address):
|
|
143
|
+
print(f"Error: Provided email is invalid. Must match pattern: [a-z0-9]+@({domain_regex})", file=sys.stderr)
|
|
144
|
+
sys.exit(1)
|
|
145
|
+
else:
|
|
146
|
+
# Generate random username
|
|
147
|
+
username = "".join(random.choices(string.ascii_lowercase + string.digits, k=11))
|
|
148
|
+
domain = random.choice(domains)
|
|
149
|
+
email_address = f"{username}@{domain}"
|
|
150
|
+
|
|
151
|
+
# Create account on mail.tm
|
|
152
|
+
try:
|
|
153
|
+
response = requests.post(
|
|
154
|
+
f"{API_URL}accounts",
|
|
155
|
+
json={"address": email_address, "password": self.password},
|
|
156
|
+
headers=HEADERS,
|
|
157
|
+
timeout=10,
|
|
158
|
+
)
|
|
159
|
+
if response.status_code not in [200, 201]:
|
|
160
|
+
print(f"Error creating account: {response.text}", file=sys.stderr)
|
|
161
|
+
sys.exit(1)
|
|
162
|
+
except requests.RequestException as e:
|
|
163
|
+
print(f"Error creating account: {e}", file=sys.stderr)
|
|
164
|
+
sys.exit(1)
|
|
165
|
+
|
|
166
|
+
self.email_file.write_text(email_address)
|
|
167
|
+
self.password_file.write_text(self.password)
|
|
168
|
+
return email_address
|
|
169
|
+
|
|
170
|
+
def list_emails(self):
|
|
171
|
+
"""List all received emails."""
|
|
172
|
+
self.get_email_address()
|
|
173
|
+
self._get_token()
|
|
174
|
+
|
|
175
|
+
try:
|
|
176
|
+
headers = HEADERS.copy()
|
|
177
|
+
headers["Authorization"] = f"Bearer {self.token}"
|
|
178
|
+
response = requests.get(
|
|
179
|
+
f"{API_URL}messages",
|
|
180
|
+
headers=headers,
|
|
181
|
+
timeout=10,
|
|
182
|
+
)
|
|
183
|
+
response.raise_for_status()
|
|
184
|
+
data = response.json()
|
|
185
|
+
emails = data.get("hydra:member", [])
|
|
186
|
+
except requests.RequestException as e:
|
|
187
|
+
print(f"Error fetching emails: {e}", file=sys.stderr)
|
|
188
|
+
sys.exit(1)
|
|
189
|
+
|
|
190
|
+
print(f"[ Inbox for {self.email_address} ]\n")
|
|
191
|
+
|
|
192
|
+
if not emails:
|
|
193
|
+
print("No new mail")
|
|
194
|
+
return
|
|
195
|
+
|
|
196
|
+
# Print emails in a formatted table
|
|
197
|
+
print(f"{'ID':<40} {'From':<40} {'Subject'}")
|
|
198
|
+
print("-" * 100)
|
|
199
|
+
for email in emails:
|
|
200
|
+
email_id = email.get("id", "")
|
|
201
|
+
from_addr = email.get("from", {}).get("address", "") if isinstance(email.get("from"), dict) else ""
|
|
202
|
+
subject = email.get("subject", "")
|
|
203
|
+
# Truncate long fields for display
|
|
204
|
+
from_addr = from_addr[:38] + ".." if len(from_addr) > 40 else from_addr
|
|
205
|
+
subject = subject[:50] + ".." if len(subject) > 50 else subject
|
|
206
|
+
print(f"{email_id:<40} {from_addr:<40} {subject}")
|
|
207
|
+
|
|
208
|
+
def view_email(self, email_id):
|
|
209
|
+
"""View a specific email by ID."""
|
|
210
|
+
self.get_email_address()
|
|
211
|
+
self._get_token()
|
|
212
|
+
|
|
213
|
+
try:
|
|
214
|
+
headers = HEADERS.copy()
|
|
215
|
+
headers["Authorization"] = f"Bearer {self.token}"
|
|
216
|
+
response = requests.get(
|
|
217
|
+
f"{API_URL}messages/{email_id}",
|
|
218
|
+
headers=headers,
|
|
219
|
+
timeout=10,
|
|
220
|
+
)
|
|
221
|
+
response.raise_for_status()
|
|
222
|
+
data = response.json()
|
|
223
|
+
except requests.RequestException as e:
|
|
224
|
+
print(f"Error fetching email: {e}", file=sys.stderr)
|
|
225
|
+
sys.exit(1)
|
|
226
|
+
|
|
227
|
+
if not data.get("id"):
|
|
228
|
+
print("Error: Message not found", file=sys.stderr)
|
|
229
|
+
sys.exit(1)
|
|
230
|
+
|
|
231
|
+
from_dict = data.get("from", {})
|
|
232
|
+
from_addr = from_dict.get("address", "") if isinstance(from_dict, dict) else ""
|
|
233
|
+
subject = data.get("subject", "")
|
|
234
|
+
html_body = data.get("html", "")
|
|
235
|
+
text_body = data.get("text", "")
|
|
236
|
+
attachments = data.get("attachments", [])
|
|
237
|
+
|
|
238
|
+
# Use textBody if htmlBody is empty
|
|
239
|
+
if not html_body:
|
|
240
|
+
html_body = f"<pre>{text_body}</pre>"
|
|
241
|
+
|
|
242
|
+
# Build HTML content
|
|
243
|
+
html_content = f"""<pre><b>To: </b>{self.email_address}
|
|
244
|
+
<b>From: </b>{from_addr}
|
|
245
|
+
<b>Subject: </b>{subject}</pre>
|
|
246
|
+
{html_body}
|
|
247
|
+
"""
|
|
248
|
+
|
|
249
|
+
# Handle attachments
|
|
250
|
+
if attachments:
|
|
251
|
+
html_content += "<br><b>[Attachments]</b><br>"
|
|
252
|
+
for attachment in attachments:
|
|
253
|
+
filename = attachment.get("name", "") if isinstance(attachment, dict) else str(attachment)
|
|
254
|
+
download_url = f"{API_URL}messages/{email_id}/html"
|
|
255
|
+
|
|
256
|
+
if self.raw_text:
|
|
257
|
+
html_content += f"{download_url} [{filename}]<br>"
|
|
258
|
+
else:
|
|
259
|
+
html_content += f'<a href="{download_url}" download="{filename}">{filename}</a><br>'
|
|
260
|
+
|
|
261
|
+
# Save to file
|
|
262
|
+
self.html_file.write_text(html_content)
|
|
263
|
+
|
|
264
|
+
if self.raw_text:
|
|
265
|
+
# Convert HTML to text using w3m or beautifulsoup
|
|
266
|
+
self._print_text_version()
|
|
267
|
+
else:
|
|
268
|
+
# Open with browser
|
|
269
|
+
try:
|
|
270
|
+
subprocess.run([self.browser, str(self.html_file)], check=True)
|
|
271
|
+
except FileNotFoundError:
|
|
272
|
+
print(f"Error: Browser '{self.browser}' not found", file=sys.stderr)
|
|
273
|
+
sys.exit(1)
|
|
274
|
+
except subprocess.CalledProcessError as e:
|
|
275
|
+
print(f"Error opening browser: {e}", file=sys.stderr)
|
|
276
|
+
sys.exit(1)
|
|
277
|
+
|
|
278
|
+
def _print_text_version(self):
|
|
279
|
+
"""Print text version of email using w3m -dump or BeautifulSoup."""
|
|
280
|
+
try:
|
|
281
|
+
result = subprocess.run(
|
|
282
|
+
["w3m", "-dump", str(self.html_file)],
|
|
283
|
+
capture_output=True,
|
|
284
|
+
text=True,
|
|
285
|
+
check=True,
|
|
286
|
+
)
|
|
287
|
+
print(result.stdout)
|
|
288
|
+
except FileNotFoundError:
|
|
289
|
+
# Fallback to BeautifulSoup if w3m is not available
|
|
290
|
+
soup = BeautifulSoup(self.html_file.read_text(), "html.parser")
|
|
291
|
+
print(soup.get_text())
|
|
292
|
+
except subprocess.CalledProcessError as e:
|
|
293
|
+
print(f"Error converting to text: {e}", file=sys.stderr)
|
|
294
|
+
sys.exit(1)
|
|
295
|
+
|
|
296
|
+
def view_recent_email(self):
|
|
297
|
+
"""View the most recent email."""
|
|
298
|
+
self.get_email_address()
|
|
299
|
+
self._get_token()
|
|
300
|
+
|
|
301
|
+
try:
|
|
302
|
+
headers = HEADERS.copy()
|
|
303
|
+
headers["Authorization"] = f"Bearer {self.token}"
|
|
304
|
+
response = requests.get(
|
|
305
|
+
f"{API_URL}messages",
|
|
306
|
+
headers=headers,
|
|
307
|
+
timeout=10,
|
|
308
|
+
)
|
|
309
|
+
response.raise_for_status()
|
|
310
|
+
data = response.json()
|
|
311
|
+
emails = data.get("hydra:member", [])
|
|
312
|
+
except requests.RequestException as e:
|
|
313
|
+
print(f"Error fetching emails: {e}", file=sys.stderr)
|
|
314
|
+
sys.exit(1)
|
|
315
|
+
|
|
316
|
+
if not emails:
|
|
317
|
+
print("No new mail")
|
|
318
|
+
return
|
|
319
|
+
|
|
320
|
+
# Get the most recent email (first in the list)
|
|
321
|
+
recent_email_id = emails[0].get("id")
|
|
322
|
+
self.view_email(recent_email_id)
|
|
323
|
+
|
|
324
|
+
def copy_to_clipboard(self):
|
|
325
|
+
"""Copy email address to clipboard."""
|
|
326
|
+
self.get_email_address()
|
|
327
|
+
|
|
328
|
+
try:
|
|
329
|
+
# Parse the clipboard command
|
|
330
|
+
cmd_parts = self.clipboard_cmd.split()
|
|
331
|
+
process = subprocess.Popen(
|
|
332
|
+
cmd_parts,
|
|
333
|
+
stdin=subprocess.PIPE,
|
|
334
|
+
stdout=subprocess.PIPE,
|
|
335
|
+
stderr=subprocess.PIPE,
|
|
336
|
+
)
|
|
337
|
+
process.communicate(input=self.email_address.encode())
|
|
338
|
+
print(f"Email address '{self.email_address}' copied to clipboard")
|
|
339
|
+
except FileNotFoundError:
|
|
340
|
+
print(f"Error: Clipboard command '{self.clipboard_cmd}' not found", file=sys.stderr)
|
|
341
|
+
sys.exit(1)
|
|
342
|
+
except Exception as e:
|
|
343
|
+
print(f"Error copying to clipboard: {e}", file=sys.stderr)
|
|
344
|
+
sys.exit(1)
|
|
345
|
+
|
|
346
|
+
def show_domains(self):
|
|
347
|
+
"""Show list of available domains."""
|
|
348
|
+
domains = self.get_domains()
|
|
349
|
+
print("List of available domains:")
|
|
350
|
+
for domain in domains:
|
|
351
|
+
print(f" - {domain}")
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def check_dependencies(browser, clipboard_cmd):
|
|
355
|
+
"""Check if required dependencies are installed."""
|
|
356
|
+
missing = []
|
|
357
|
+
|
|
358
|
+
# Check for w3m (or custom browser)
|
|
359
|
+
if not check_command(browser):
|
|
360
|
+
missing.append(browser)
|
|
361
|
+
|
|
362
|
+
# Check for clipboard command
|
|
363
|
+
clipboard_base = clipboard_cmd.split()[0]
|
|
364
|
+
if not check_command(clipboard_base):
|
|
365
|
+
missing.append(clipboard_base)
|
|
366
|
+
|
|
367
|
+
if missing:
|
|
368
|
+
print(f"Error: Could not find the following dependencies: {' '.join(missing)}", file=sys.stderr)
|
|
369
|
+
sys.exit(1)
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
def check_command(cmd):
|
|
373
|
+
"""Check if a command exists."""
|
|
374
|
+
return subprocess.run(
|
|
375
|
+
["which", cmd],
|
|
376
|
+
capture_output=True,
|
|
377
|
+
check=False,
|
|
378
|
+
).returncode == 0
|
|
379
|
+
|
|
380
|
+
|
|
381
|
+
def main():
|
|
382
|
+
"""Main entry point for tmpmail."""
|
|
383
|
+
parser = argparse.ArgumentParser(
|
|
384
|
+
prog="tmpmail",
|
|
385
|
+
description="A temporary email right from your terminal",
|
|
386
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
387
|
+
epilog="""
|
|
388
|
+
Examples:
|
|
389
|
+
tmpmail --generate Create random email
|
|
390
|
+
tmpmail -g myemail@domain.com Create custom email
|
|
391
|
+
tmpmail View the inbox
|
|
392
|
+
tmpmail 12345 View email by ID
|
|
393
|
+
tmpmail -r View most recent email
|
|
394
|
+
tmpmail -t 12345 View email as raw text
|
|
395
|
+
tmpmail -c Copy email address to clipboard
|
|
396
|
+
tmpmail -d Show available domains
|
|
397
|
+
""",
|
|
398
|
+
)
|
|
399
|
+
|
|
400
|
+
parser.add_argument(
|
|
401
|
+
"-g",
|
|
402
|
+
"--generate",
|
|
403
|
+
nargs="?",
|
|
404
|
+
const="__random__",
|
|
405
|
+
metavar="ADDRESS",
|
|
406
|
+
help="Generate a new email address, either randomly or with specified ADDRESS",
|
|
407
|
+
)
|
|
408
|
+
parser.add_argument(
|
|
409
|
+
"-b",
|
|
410
|
+
"--browser",
|
|
411
|
+
metavar="BROWSER",
|
|
412
|
+
default=DEFAULT_BROWSER,
|
|
413
|
+
help=f"Specify browser to render HTML (default: {DEFAULT_BROWSER})",
|
|
414
|
+
)
|
|
415
|
+
parser.add_argument(
|
|
416
|
+
"-t",
|
|
417
|
+
"--text",
|
|
418
|
+
action="store_true",
|
|
419
|
+
help="View email as raw text (remove HTML tags)",
|
|
420
|
+
)
|
|
421
|
+
parser.add_argument(
|
|
422
|
+
"-r",
|
|
423
|
+
"--recent",
|
|
424
|
+
action="store_true",
|
|
425
|
+
help="View the most recent email message",
|
|
426
|
+
)
|
|
427
|
+
parser.add_argument(
|
|
428
|
+
"-c",
|
|
429
|
+
"--copy",
|
|
430
|
+
action="store_true",
|
|
431
|
+
help="Copy the email address to clipboard",
|
|
432
|
+
)
|
|
433
|
+
parser.add_argument(
|
|
434
|
+
"-d",
|
|
435
|
+
"--domains",
|
|
436
|
+
action="store_true",
|
|
437
|
+
help="Show list of available domains",
|
|
438
|
+
)
|
|
439
|
+
parser.add_argument(
|
|
440
|
+
"--clipboard-cmd",
|
|
441
|
+
metavar="COMMAND",
|
|
442
|
+
default=DEFAULT_CLIPBOARD_CMD,
|
|
443
|
+
help=f"Command for copying to clipboard (default: {DEFAULT_CLIPBOARD_CMD})",
|
|
444
|
+
)
|
|
445
|
+
parser.add_argument(
|
|
446
|
+
"--version",
|
|
447
|
+
action="version",
|
|
448
|
+
version=f"%(prog)s {VERSION}",
|
|
449
|
+
)
|
|
450
|
+
parser.add_argument(
|
|
451
|
+
"email_id",
|
|
452
|
+
nargs="?",
|
|
453
|
+
metavar="ID",
|
|
454
|
+
help="View email message with specified ID",
|
|
455
|
+
)
|
|
456
|
+
|
|
457
|
+
args = parser.parse_args()
|
|
458
|
+
|
|
459
|
+
tmpmail = TmpMail()
|
|
460
|
+
tmpmail.browser = args.browser
|
|
461
|
+
tmpmail.clipboard_cmd = args.clipboard_cmd
|
|
462
|
+
tmpmail.raw_text = args.text
|
|
463
|
+
|
|
464
|
+
# Handle --domains and --version first (don't require dependencies)
|
|
465
|
+
if args.domains:
|
|
466
|
+
tmpmail.show_domains()
|
|
467
|
+
sys.exit(0)
|
|
468
|
+
|
|
469
|
+
# Handle --generate (don't require browser/clipboard dependencies)
|
|
470
|
+
if args.generate is not None:
|
|
471
|
+
if args.generate == "__random__":
|
|
472
|
+
email = tmpmail.generate_email_address()
|
|
473
|
+
else:
|
|
474
|
+
email = tmpmail.generate_email_address(args.generate)
|
|
475
|
+
print(email)
|
|
476
|
+
sys.exit(0)
|
|
477
|
+
|
|
478
|
+
# For other operations, check dependencies as needed
|
|
479
|
+
# Check dependencies for operations that need them
|
|
480
|
+
if args.recent or args.email_id:
|
|
481
|
+
check_dependencies(args.browser, args.clipboard_cmd)
|
|
482
|
+
|
|
483
|
+
# Handle --copy
|
|
484
|
+
if args.copy:
|
|
485
|
+
check_dependencies(args.browser, args.clipboard_cmd)
|
|
486
|
+
tmpmail.copy_to_clipboard()
|
|
487
|
+
sys.exit(0)
|
|
488
|
+
|
|
489
|
+
# Handle --recent
|
|
490
|
+
if args.recent:
|
|
491
|
+
tmpmail.view_recent_email()
|
|
492
|
+
sys.exit(0)
|
|
493
|
+
|
|
494
|
+
# Handle email ID argument
|
|
495
|
+
if args.email_id:
|
|
496
|
+
tmpmail.view_email(args.email_id)
|
|
497
|
+
sys.exit(0)
|
|
498
|
+
|
|
499
|
+
# Default: list emails (no dependencies needed)
|
|
500
|
+
tmpmail.list_emails()
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
if __name__ == "__main__":
|
|
504
|
+
main()
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tmpmail-cli
|
|
3
|
+
Version: 1.2.3
|
|
4
|
+
Summary: A temporary email right from your terminal
|
|
5
|
+
Author-email: Siddharth Dushantha <siddharth.dushantha@gmail.com>
|
|
6
|
+
Maintainer-email: Siddharth Dushantha <siddharth.dushantha@gmail.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/sdushantha/tmpmail
|
|
9
|
+
Project-URL: Repository, https://github.com/sdushantha/tmpmail.git
|
|
10
|
+
Project-URL: BugTracker, https://github.com/sdushantha/tmpmail/issues
|
|
11
|
+
Keywords: email,temporary,cli,1secmail,mailtm
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Topic :: Communications :: Email
|
|
24
|
+
Classifier: Topic :: Utilities
|
|
25
|
+
Requires-Python: >=3.7
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
License-File: LICENSE
|
|
28
|
+
Requires-Dist: requests>=2.25.0
|
|
29
|
+
Requires-Dist: beautifulsoup4>=4.9.0
|
|
30
|
+
Provides-Extra: dev
|
|
31
|
+
Requires-Dist: pytest>=6.0; extra == "dev"
|
|
32
|
+
Requires-Dist: black>=22.0; extra == "dev"
|
|
33
|
+
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
34
|
+
Dynamic: license-file
|
|
35
|
+
|
|
36
|
+
<h1 align="center">
|
|
37
|
+
<img src="images/logo.png">
|
|
38
|
+
</h1>
|
|
39
|
+
<p align="center"> A temporary email right from your terminal</p><br>
|
|
40
|
+
|
|
41
|
+
<img src="images/demo.gif" align="right"> `tmpmail` is a command line utility that allows you to create a temporary email address
|
|
42
|
+
and receive emails to the temporary email address. It uses 1secmail's [API](https://www.1secmail.com/api/)
|
|
43
|
+
to receive emails.
|
|
44
|
+
|
|
45
|
+
By default `w3m` is used to render the HTML emails on the terminal.
|
|
46
|
+
But if you prefer another text based web browser or would rather view the email in a GUI web browser such as Firefox, simply
|
|
47
|
+
use the `--browser` argument followed by the command needed to launch the web browser of your choice.
|
|
48
|
+
|
|
49
|
+
<br>
|
|
50
|
+
<br>
|
|
51
|
+
<br>
|
|
52
|
+
|
|
53
|
+
## Dependencies
|
|
54
|
+
|
|
55
|
+
**Python dependencies** (installed automatically with pip):
|
|
56
|
+
- `requests`
|
|
57
|
+
- `beautifulsoup4`
|
|
58
|
+
|
|
59
|
+
**System dependencies** (required for full functionality):
|
|
60
|
+
- `w3m` (or another browser for rendering HTML emails)
|
|
61
|
+
- `xclip` (or another clipboard utility for the `--copy` feature)
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
### Install with pip (Recommended)
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# Install with pip
|
|
69
|
+
$ pip install tmpmail-cli
|
|
70
|
+
|
|
71
|
+
# Or with pipx for an isolated installation
|
|
72
|
+
$ pipx install tmpmail-cli
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Install from source
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
$ git clone https://github.com/sdushantha/tmpmail.git
|
|
79
|
+
$ cd tmpmail
|
|
80
|
+
$ pip install .
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Install locally (Legacy shell script)
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
# Download the tmpmail file and make it executable
|
|
87
|
+
$ curl -L "https://raw.githubusercontent.com/sdushantha/tmpmail/master/tmpmail" > tmpmail && chmod +x tmpmail
|
|
88
|
+
|
|
89
|
+
# Then move it somewhere in your $PATH. Here is an example:
|
|
90
|
+
$ mv tmpmail ~/bin/
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### AUR
|
|
94
|
+
`tmpmail` is available on the [AUR](https://aur.archlinux.org/packages/tmpmail-git/), which is currently being maintained by [Benjamin Bädorf](https://github.com/b12f)
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
$ yay -S tmpmail-git
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### [Pacstall](https://github.com/pacstall/pacstall) (Debian/Ubuntu)
|
|
101
|
+
`tmpmail` is available on the [pacstall-programs repository](https://github.com/pacstall/pacstall-programs/blob/master/packages/tmpmail-bin/tmpmail-bin.pacscript), which is being currently being maintained by [wizard-28](https://github.com/wizard-28)
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
$ pacstall -I tmpmail-bin
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Nixpkgs
|
|
108
|
+
`tmpmail` is also available in the [nix package collection (only unstable currently)](https://search.nixos.org/packages?channel=unstable&show=tmpmail&from=0&size=50&sort=relevance&query=tmpmail), which is maintained by [legendofmiracles](https://github.com/legendofmiracles)
|
|
109
|
+
|
|
110
|
+
Either add it to your system packages, install it with nix-env or try it out in a ephemeral nix-shell `nix-shell -p tmpmail`
|
|
111
|
+
|
|
112
|
+
### Docker
|
|
113
|
+
|
|
114
|
+
requirements:
|
|
115
|
+
- [docker](https://www.docker.com/)
|
|
116
|
+
- clone this repo
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
$ docker build -t mail .; # Dockerfile available in source code
|
|
120
|
+
$ docker run -it mail;
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Usage
|
|
124
|
+
```console
|
|
125
|
+
$ tmpmail --help
|
|
126
|
+
tmpmail
|
|
127
|
+
tmpmail -h | --version
|
|
128
|
+
tmpmail -g [ADDRESS]
|
|
129
|
+
tmpmail [-t | -b BROWSER] -r | ID
|
|
130
|
+
|
|
131
|
+
When called with no option and no argument, tmpmail lists the messages in
|
|
132
|
+
the inbox and their numeric IDs. When called with one argument, tmpmail
|
|
133
|
+
shows the email message with specified ID.
|
|
134
|
+
|
|
135
|
+
-b, --browser BROWSER
|
|
136
|
+
Specify BROWSER that is used to render the HTML of
|
|
137
|
+
the email (default: w3m)
|
|
138
|
+
--clipboard-cmd COMMAND
|
|
139
|
+
Specify the COMMAND to use for copying the email address to your
|
|
140
|
+
clipboard (default: xclip -selection c)
|
|
141
|
+
-c, --copy
|
|
142
|
+
Copy the email address to your clipboard
|
|
143
|
+
-d, --domains
|
|
144
|
+
Show list of available domains
|
|
145
|
+
-g, --generate [ADDRESS]
|
|
146
|
+
Generate a new email address, either the specified ADDRESS, or
|
|
147
|
+
randomly create one
|
|
148
|
+
-h, --help
|
|
149
|
+
Show help
|
|
150
|
+
-r, --recent
|
|
151
|
+
View the most recent email message
|
|
152
|
+
-t, --text
|
|
153
|
+
View the email as raw text, where all the HTML tags are removed.
|
|
154
|
+
Without this option, HTML is used.
|
|
155
|
+
--version
|
|
156
|
+
Show version
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
### Examples
|
|
160
|
+
Create random email
|
|
161
|
+
```console
|
|
162
|
+
$ tmpmail --generate
|
|
163
|
+
xoithrjagpx@1secmail.net
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Create custom email
|
|
167
|
+
```console
|
|
168
|
+
$ tmpmail --generate mycustomemail@1secmail.com
|
|
169
|
+
mycustomemail@1secmail.com
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
View the inbox
|
|
173
|
+
```console
|
|
174
|
+
$ tmpmail
|
|
175
|
+
[ Inbox for wdebivbyjor@1secmail.com ]
|
|
176
|
+
|
|
177
|
+
83414443 username@example.com Test Email
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
View the email
|
|
181
|
+
```console
|
|
182
|
+
$ tmpmail 83414443
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
View the most recent email
|
|
186
|
+
```console
|
|
187
|
+
$ tmpmail -r
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
View emails as pure text
|
|
191
|
+
```console
|
|
192
|
+
$ tmpmail -t 83414443
|
|
193
|
+
To: wdebivbyjor@1secmail.com
|
|
194
|
+
From: username@example.com
|
|
195
|
+
Subject: Test Email
|
|
196
|
+
|
|
197
|
+
Hello World
|
|
198
|
+
|
|
199
|
+
[Attachments]
|
|
200
|
+
https://is.gd/aBCdEf [apple.jpg]
|
|
201
|
+
https://is.gd/AbCDeF [ball.jpg]
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Credits
|
|
205
|
+
This script is heavily inspired by Mitch Weaver's [`1secmail`](https://github.com/mitchweaver/bin/blob/master/OLD/1secmail) script
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/tmpmail/__init__.py
|
|
5
|
+
src/tmpmail/__main__.py
|
|
6
|
+
src/tmpmail/cli.py
|
|
7
|
+
src/tmpmail_cli.egg-info/PKG-INFO
|
|
8
|
+
src/tmpmail_cli.egg-info/SOURCES.txt
|
|
9
|
+
src/tmpmail_cli.egg-info/dependency_links.txt
|
|
10
|
+
src/tmpmail_cli.egg-info/entry_points.txt
|
|
11
|
+
src/tmpmail_cli.egg-info/requires.txt
|
|
12
|
+
src/tmpmail_cli.egg-info/top_level.txt
|
|
13
|
+
tests/test_tmpmail.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tmpmail
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Tests for tmpmail package."""
|
|
2
|
+
|
|
3
|
+
import pytest
|
|
4
|
+
from tmpmail import TmpMail, __version__
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def test_version():
|
|
8
|
+
"""Test that the version is set correctly."""
|
|
9
|
+
assert __version__ == "1.2.3"
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def test_tmpmail_initialization():
|
|
13
|
+
"""Test that TmpMail class initializes correctly."""
|
|
14
|
+
tmpmail = TmpMail()
|
|
15
|
+
assert tmpmail.tmpmail_dir is not None
|
|
16
|
+
assert tmpmail.browser == "w3m"
|
|
17
|
+
assert tmpmail.raw_text is False
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_get_domains():
|
|
21
|
+
"""Test getting available domains."""
|
|
22
|
+
tmpmail = TmpMail()
|
|
23
|
+
domains = tmpmail.get_domains()
|
|
24
|
+
assert isinstance(domains, list)
|
|
25
|
+
assert len(domains) > 0
|
|
26
|
+
assert all(isinstance(d, str) for d in domains)
|