tgclip 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- tgclip-0.1.0/LICENSE +21 -0
- tgclip-0.1.0/PKG-INFO +237 -0
- tgclip-0.1.0/README.md +220 -0
- tgclip-0.1.0/pyproject.toml +33 -0
- tgclip-0.1.0/setup.cfg +4 -0
- tgclip-0.1.0/src/tgclip/__init__.py +0 -0
- tgclip-0.1.0/src/tgclip/__main__.py +1 -0
- tgclip-0.1.0/src/tgclip/clipboard.py +5 -0
- tgclip-0.1.0/src/tgclip/config.py +55 -0
- tgclip-0.1.0/src/tgclip/main.py +259 -0
- tgclip-0.1.0/src/tgclip/telegram.py +89 -0
- tgclip-0.1.0/src/tgclip/ui.py +79 -0
- tgclip-0.1.0/src/tgclip/utils.py +38 -0
- tgclip-0.1.0/src/tgclip.egg-info/PKG-INFO +237 -0
- tgclip-0.1.0/src/tgclip.egg-info/SOURCES.txt +17 -0
- tgclip-0.1.0/src/tgclip.egg-info/dependency_links.txt +1 -0
- tgclip-0.1.0/src/tgclip.egg-info/entry_points.txt +2 -0
- tgclip-0.1.0/src/tgclip.egg-info/requires.txt +5 -0
- tgclip-0.1.0/src/tgclip.egg-info/top_level.txt +1 -0
tgclip-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Aditya Jaiswal
|
|
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.
|
tgclip-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tgclip
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Send clipboard content to Telegram instantly.
|
|
5
|
+
Author: CyberLeafy
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: telegram,clipboard,cli,terminal,python
|
|
8
|
+
Requires-Python: >=3.14
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: platformdirs>=4.10.0
|
|
12
|
+
Requires-Dist: pyperclip>=1.11.0
|
|
13
|
+
Requires-Dist: requests>=2.34.2
|
|
14
|
+
Requires-Dist: rich>=15.0.0
|
|
15
|
+
Requires-Dist: typer>=0.26.8
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
<div align="center">
|
|
19
|
+
|
|
20
|
+
# 📋 TGCLIP
|
|
21
|
+
|
|
22
|
+
### Instantly send clipboard content or text from your computer to Telegram.
|
|
23
|
+
|
|
24
|
+
[](https://pypi.org/project/tgclip/)
|
|
25
|
+
[](https://www.python.org/)
|
|
26
|
+
[](#-license)
|
|
27
|
+
[](https://core.telegram.org/bots)
|
|
28
|
+
|
|
29
|
+
A lightweight CLI that moves text, code, links, and commands from your desktop straight to Telegram — built for developers, students, and anyone who lives between a laptop and a phone.
|
|
30
|
+
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<br>
|
|
34
|
+
|
|
35
|
+
## Table of Contents
|
|
36
|
+
|
|
37
|
+
- [Features](#-features)
|
|
38
|
+
- [Installation](#-installation)
|
|
39
|
+
- [Prerequisites](#-prerequisites)
|
|
40
|
+
- [Quick Start](#-quick-start)
|
|
41
|
+
- [Commands](#-commands)
|
|
42
|
+
- [Workflow](#-workflow)
|
|
43
|
+
- [Use Cases](#-use-cases)
|
|
44
|
+
- [Privacy](#-privacy)
|
|
45
|
+
- [Troubleshooting](#-troubleshooting)
|
|
46
|
+
- [Requirements](#-requirements)
|
|
47
|
+
- [Issues](#-issues)
|
|
48
|
+
- [License](#-license)
|
|
49
|
+
|
|
50
|
+
<br>
|
|
51
|
+
|
|
52
|
+
## ⚡ Features
|
|
53
|
+
|
|
54
|
+
<table>
|
|
55
|
+
<tr><td width="40">🚀</td><td>Simple one-time setup</td></tr>
|
|
56
|
+
<tr><td>📋</td><td>Send clipboard content instantly</td></tr>
|
|
57
|
+
<tr><td>✍️</td><td>Send custom text directly from the terminal</td></tr>
|
|
58
|
+
<tr><td>👀</td><td>Clipboard watch mode</td></tr>
|
|
59
|
+
<tr><td>💻</td><td>Interactive shell mode</td></tr>
|
|
60
|
+
<tr><td>⚙️</td><td>Easy configuration management</td></tr>
|
|
61
|
+
<tr><td>🩺</td><td>Built-in diagnostics with <code>doctor</code></td></tr>
|
|
62
|
+
<tr><td>🔄</td><td>Reset configuration anytime</td></tr>
|
|
63
|
+
<tr><td>🎨</td><td>Clean, colorful terminal UI powered by Rich</td></tr>
|
|
64
|
+
</table>
|
|
65
|
+
|
|
66
|
+
<br>
|
|
67
|
+
|
|
68
|
+
## 📦 Installation
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install tgclip
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Verify it worked:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
tgclip
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
<br>
|
|
81
|
+
|
|
82
|
+
## ✅ Prerequisites
|
|
83
|
+
|
|
84
|
+
| Requirement | Details |
|
|
85
|
+
|---|---|
|
|
86
|
+
| Telegram account | Any personal account |
|
|
87
|
+
| Telegram Bot | Created via [@BotFather](https://t.me/BotFather) |
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
<br>
|
|
91
|
+
|
|
92
|
+
## 🚀 Quick Start
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
tgclip init
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
You'll be prompted for:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
① Your name
|
|
102
|
+
② Telegram Bot Token
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
> 💾 Configuration is stored **locally** on your machine — nothing is uploaded anywhere else.
|
|
106
|
+
|
|
107
|
+
<br>
|
|
108
|
+
|
|
109
|
+
## 🛠 Commands
|
|
110
|
+
|
|
111
|
+
<details open>
|
|
112
|
+
<summary><b><code>tgclip init</code></b> — Initialize</summary>
|
|
113
|
+
<br>
|
|
114
|
+
|
|
115
|
+
Configure TGCLIP for first-time use.
|
|
116
|
+
</details>
|
|
117
|
+
|
|
118
|
+
<details open>
|
|
119
|
+
<summary><b><code>tgclip send</code></b> — Send</summary>
|
|
120
|
+
<br>
|
|
121
|
+
|
|
122
|
+
Send the current clipboard content to Telegram.
|
|
123
|
+
</details>
|
|
124
|
+
|
|
125
|
+
<details open>
|
|
126
|
+
<summary><b><code>tgclip watch</code></b> — Watch</summary>
|
|
127
|
+
<br>
|
|
128
|
+
|
|
129
|
+
Continuously monitor the clipboard and auto-send anything newly copied.
|
|
130
|
+
Stop with `Ctrl + C`.
|
|
131
|
+
</details>
|
|
132
|
+
|
|
133
|
+
<details open>
|
|
134
|
+
<summary><b><code>tgclip shell</code></b> — Shell</summary>
|
|
135
|
+
<br>
|
|
136
|
+
|
|
137
|
+
Launch an interactive shell for sending multiple messages without restarting the command.
|
|
138
|
+
Exit with `/exit` or `Ctrl + C`.
|
|
139
|
+
</details>
|
|
140
|
+
|
|
141
|
+
<details open>
|
|
142
|
+
<summary><b><code>tgclip config</code></b> — Configuration</summary>
|
|
143
|
+
<br>
|
|
144
|
+
|
|
145
|
+
Display your current configuration.
|
|
146
|
+
</details>
|
|
147
|
+
|
|
148
|
+
<details open>
|
|
149
|
+
<summary><b><code>tgclip doctor</code></b> — Doctor</summary>
|
|
150
|
+
<br>
|
|
151
|
+
|
|
152
|
+
Runs a full health check:
|
|
153
|
+
|
|
154
|
+
- ☑ Configuration
|
|
155
|
+
- ☑ Clipboard access
|
|
156
|
+
- ☑ Internet connectivity
|
|
157
|
+
- ☑ Telegram API access
|
|
158
|
+
- ☑ Bot token
|
|
159
|
+
- ☑ Chat ID
|
|
160
|
+
</details>
|
|
161
|
+
|
|
162
|
+
<details open>
|
|
163
|
+
<summary><b><code>tgclip reset</code></b> — Reset</summary>
|
|
164
|
+
<br>
|
|
165
|
+
|
|
166
|
+
Wipes the current configuration so you can start fresh.
|
|
167
|
+
</details>
|
|
168
|
+
|
|
169
|
+
<br>
|
|
170
|
+
|
|
171
|
+
## 🔁 Workflow
|
|
172
|
+
|
|
173
|
+
```mermaid
|
|
174
|
+
flowchart LR
|
|
175
|
+
A[📄 Copy text] --> B[tgclip send]
|
|
176
|
+
B --> C[✈️ Telegram]
|
|
177
|
+
C --> D[📱 Open on phone]
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
<br>
|
|
181
|
+
|
|
182
|
+
## 💡 Use Cases
|
|
183
|
+
|
|
184
|
+
- 🧩 Send code snippets to your phone
|
|
185
|
+
- 🔗 Transfer commands between devices
|
|
186
|
+
- 📝 Save temporary notes
|
|
187
|
+
- 🌐 Share links instantly
|
|
188
|
+
- 📤 Move terminal output
|
|
189
|
+
- 🔄 Continue work from mobile
|
|
190
|
+
|
|
191
|
+
<br>
|
|
192
|
+
|
|
193
|
+
## 🔒 Privacy
|
|
194
|
+
|
|
195
|
+
TGCLIP talks **directly** to the Telegram Bot API — nothing else is in the loop.
|
|
196
|
+
|
|
197
|
+
- ✔ Configuration stays on your local machine
|
|
198
|
+
- ✔ No external servers, no telemetry, no middleman
|
|
199
|
+
|
|
200
|
+
<br>
|
|
201
|
+
|
|
202
|
+
## 🧰 Troubleshooting
|
|
203
|
+
|
|
204
|
+
| Problem | Fix |
|
|
205
|
+
|---|---|
|
|
206
|
+
| Something's not working | `tgclip doctor` |
|
|
207
|
+
| Need to start over | `tgclip reset` → `tgclip init` |
|
|
208
|
+
| Forgot a command | `tgclip --help` |
|
|
209
|
+
|
|
210
|
+
<br>
|
|
211
|
+
|
|
212
|
+
## 📋 Requirements
|
|
213
|
+
|
|
214
|
+
- Python **3.10+**
|
|
215
|
+
- A Telegram Bot
|
|
216
|
+
- An internet connection
|
|
217
|
+
|
|
218
|
+
<br>
|
|
219
|
+
|
|
220
|
+
## 🐞 Issues
|
|
221
|
+
Found a bug or have a feature request? Please open an issue on Github.
|
|
222
|
+
|
|
223
|
+
<br>
|
|
224
|
+
|
|
225
|
+
## 📄 License
|
|
226
|
+
Released under the **MIT License**.
|
|
227
|
+
|
|
228
|
+
<br>
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
<div align="center">
|
|
232
|
+
|
|
233
|
+
**Developed by CyberLeafy**
|
|
234
|
+
|
|
235
|
+
*TGCLIP — Fast. Simple. Clipboard to Telegram.* 📋➡️📱
|
|
236
|
+
|
|
237
|
+
</div>
|
tgclip-0.1.0/README.md
ADDED
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
# 📋 TGCLIP
|
|
4
|
+
|
|
5
|
+
### Instantly send clipboard content or text from your computer to Telegram.
|
|
6
|
+
|
|
7
|
+
[](https://pypi.org/project/tgclip/)
|
|
8
|
+
[](https://www.python.org/)
|
|
9
|
+
[](#-license)
|
|
10
|
+
[](https://core.telegram.org/bots)
|
|
11
|
+
|
|
12
|
+
A lightweight CLI that moves text, code, links, and commands from your desktop straight to Telegram — built for developers, students, and anyone who lives between a laptop and a phone.
|
|
13
|
+
|
|
14
|
+
</div>
|
|
15
|
+
|
|
16
|
+
<br>
|
|
17
|
+
|
|
18
|
+
## Table of Contents
|
|
19
|
+
|
|
20
|
+
- [Features](#-features)
|
|
21
|
+
- [Installation](#-installation)
|
|
22
|
+
- [Prerequisites](#-prerequisites)
|
|
23
|
+
- [Quick Start](#-quick-start)
|
|
24
|
+
- [Commands](#-commands)
|
|
25
|
+
- [Workflow](#-workflow)
|
|
26
|
+
- [Use Cases](#-use-cases)
|
|
27
|
+
- [Privacy](#-privacy)
|
|
28
|
+
- [Troubleshooting](#-troubleshooting)
|
|
29
|
+
- [Requirements](#-requirements)
|
|
30
|
+
- [Issues](#-issues)
|
|
31
|
+
- [License](#-license)
|
|
32
|
+
|
|
33
|
+
<br>
|
|
34
|
+
|
|
35
|
+
## ⚡ Features
|
|
36
|
+
|
|
37
|
+
<table>
|
|
38
|
+
<tr><td width="40">🚀</td><td>Simple one-time setup</td></tr>
|
|
39
|
+
<tr><td>📋</td><td>Send clipboard content instantly</td></tr>
|
|
40
|
+
<tr><td>✍️</td><td>Send custom text directly from the terminal</td></tr>
|
|
41
|
+
<tr><td>👀</td><td>Clipboard watch mode</td></tr>
|
|
42
|
+
<tr><td>💻</td><td>Interactive shell mode</td></tr>
|
|
43
|
+
<tr><td>⚙️</td><td>Easy configuration management</td></tr>
|
|
44
|
+
<tr><td>🩺</td><td>Built-in diagnostics with <code>doctor</code></td></tr>
|
|
45
|
+
<tr><td>🔄</td><td>Reset configuration anytime</td></tr>
|
|
46
|
+
<tr><td>🎨</td><td>Clean, colorful terminal UI powered by Rich</td></tr>
|
|
47
|
+
</table>
|
|
48
|
+
|
|
49
|
+
<br>
|
|
50
|
+
|
|
51
|
+
## 📦 Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pip install tgclip
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Verify it worked:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
tgclip
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
<br>
|
|
64
|
+
|
|
65
|
+
## ✅ Prerequisites
|
|
66
|
+
|
|
67
|
+
| Requirement | Details |
|
|
68
|
+
|---|---|
|
|
69
|
+
| Telegram account | Any personal account |
|
|
70
|
+
| Telegram Bot | Created via [@BotFather](https://t.me/BotFather) |
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
<br>
|
|
74
|
+
|
|
75
|
+
## 🚀 Quick Start
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
tgclip init
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
You'll be prompted for:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
① Your name
|
|
85
|
+
② Telegram Bot Token
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
> 💾 Configuration is stored **locally** on your machine — nothing is uploaded anywhere else.
|
|
89
|
+
|
|
90
|
+
<br>
|
|
91
|
+
|
|
92
|
+
## 🛠 Commands
|
|
93
|
+
|
|
94
|
+
<details open>
|
|
95
|
+
<summary><b><code>tgclip init</code></b> — Initialize</summary>
|
|
96
|
+
<br>
|
|
97
|
+
|
|
98
|
+
Configure TGCLIP for first-time use.
|
|
99
|
+
</details>
|
|
100
|
+
|
|
101
|
+
<details open>
|
|
102
|
+
<summary><b><code>tgclip send</code></b> — Send</summary>
|
|
103
|
+
<br>
|
|
104
|
+
|
|
105
|
+
Send the current clipboard content to Telegram.
|
|
106
|
+
</details>
|
|
107
|
+
|
|
108
|
+
<details open>
|
|
109
|
+
<summary><b><code>tgclip watch</code></b> — Watch</summary>
|
|
110
|
+
<br>
|
|
111
|
+
|
|
112
|
+
Continuously monitor the clipboard and auto-send anything newly copied.
|
|
113
|
+
Stop with `Ctrl + C`.
|
|
114
|
+
</details>
|
|
115
|
+
|
|
116
|
+
<details open>
|
|
117
|
+
<summary><b><code>tgclip shell</code></b> — Shell</summary>
|
|
118
|
+
<br>
|
|
119
|
+
|
|
120
|
+
Launch an interactive shell for sending multiple messages without restarting the command.
|
|
121
|
+
Exit with `/exit` or `Ctrl + C`.
|
|
122
|
+
</details>
|
|
123
|
+
|
|
124
|
+
<details open>
|
|
125
|
+
<summary><b><code>tgclip config</code></b> — Configuration</summary>
|
|
126
|
+
<br>
|
|
127
|
+
|
|
128
|
+
Display your current configuration.
|
|
129
|
+
</details>
|
|
130
|
+
|
|
131
|
+
<details open>
|
|
132
|
+
<summary><b><code>tgclip doctor</code></b> — Doctor</summary>
|
|
133
|
+
<br>
|
|
134
|
+
|
|
135
|
+
Runs a full health check:
|
|
136
|
+
|
|
137
|
+
- ☑ Configuration
|
|
138
|
+
- ☑ Clipboard access
|
|
139
|
+
- ☑ Internet connectivity
|
|
140
|
+
- ☑ Telegram API access
|
|
141
|
+
- ☑ Bot token
|
|
142
|
+
- ☑ Chat ID
|
|
143
|
+
</details>
|
|
144
|
+
|
|
145
|
+
<details open>
|
|
146
|
+
<summary><b><code>tgclip reset</code></b> — Reset</summary>
|
|
147
|
+
<br>
|
|
148
|
+
|
|
149
|
+
Wipes the current configuration so you can start fresh.
|
|
150
|
+
</details>
|
|
151
|
+
|
|
152
|
+
<br>
|
|
153
|
+
|
|
154
|
+
## 🔁 Workflow
|
|
155
|
+
|
|
156
|
+
```mermaid
|
|
157
|
+
flowchart LR
|
|
158
|
+
A[📄 Copy text] --> B[tgclip send]
|
|
159
|
+
B --> C[✈️ Telegram]
|
|
160
|
+
C --> D[📱 Open on phone]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
<br>
|
|
164
|
+
|
|
165
|
+
## 💡 Use Cases
|
|
166
|
+
|
|
167
|
+
- 🧩 Send code snippets to your phone
|
|
168
|
+
- 🔗 Transfer commands between devices
|
|
169
|
+
- 📝 Save temporary notes
|
|
170
|
+
- 🌐 Share links instantly
|
|
171
|
+
- 📤 Move terminal output
|
|
172
|
+
- 🔄 Continue work from mobile
|
|
173
|
+
|
|
174
|
+
<br>
|
|
175
|
+
|
|
176
|
+
## 🔒 Privacy
|
|
177
|
+
|
|
178
|
+
TGCLIP talks **directly** to the Telegram Bot API — nothing else is in the loop.
|
|
179
|
+
|
|
180
|
+
- ✔ Configuration stays on your local machine
|
|
181
|
+
- ✔ No external servers, no telemetry, no middleman
|
|
182
|
+
|
|
183
|
+
<br>
|
|
184
|
+
|
|
185
|
+
## 🧰 Troubleshooting
|
|
186
|
+
|
|
187
|
+
| Problem | Fix |
|
|
188
|
+
|---|---|
|
|
189
|
+
| Something's not working | `tgclip doctor` |
|
|
190
|
+
| Need to start over | `tgclip reset` → `tgclip init` |
|
|
191
|
+
| Forgot a command | `tgclip --help` |
|
|
192
|
+
|
|
193
|
+
<br>
|
|
194
|
+
|
|
195
|
+
## 📋 Requirements
|
|
196
|
+
|
|
197
|
+
- Python **3.10+**
|
|
198
|
+
- A Telegram Bot
|
|
199
|
+
- An internet connection
|
|
200
|
+
|
|
201
|
+
<br>
|
|
202
|
+
|
|
203
|
+
## 🐞 Issues
|
|
204
|
+
Found a bug or have a feature request? Please open an issue on Github.
|
|
205
|
+
|
|
206
|
+
<br>
|
|
207
|
+
|
|
208
|
+
## 📄 License
|
|
209
|
+
Released under the **MIT License**.
|
|
210
|
+
|
|
211
|
+
<br>
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
<div align="center">
|
|
215
|
+
|
|
216
|
+
**Developed by CyberLeafy**
|
|
217
|
+
|
|
218
|
+
*TGCLIP — Fast. Simple. Clipboard to Telegram.* 📋➡️📱
|
|
219
|
+
|
|
220
|
+
</div>
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
[project]
|
|
7
|
+
name = "tgclip"
|
|
8
|
+
version = "0.1.0"
|
|
9
|
+
description = "Send clipboard content to Telegram instantly."
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
requires-python = ">=3.14"
|
|
12
|
+
license = { text = "MIT" }
|
|
13
|
+
authors = [
|
|
14
|
+
{ name = "CyberLeafy" }
|
|
15
|
+
]
|
|
16
|
+
keywords = [
|
|
17
|
+
"telegram",
|
|
18
|
+
"clipboard",
|
|
19
|
+
"cli",
|
|
20
|
+
"terminal",
|
|
21
|
+
"python"
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
dependencies = [
|
|
25
|
+
"platformdirs>=4.10.0",
|
|
26
|
+
"pyperclip>=1.11.0",
|
|
27
|
+
"requests>=2.34.2",
|
|
28
|
+
"rich>=15.0.0",
|
|
29
|
+
"typer>=0.26.8",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.scripts]
|
|
33
|
+
tgclip = "tgclip.main:main"
|
tgclip-0.1.0/setup.cfg
ADDED
|
File without changes
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from .main import main
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from typing import Any
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from platformdirs import user_config_dir
|
|
5
|
+
|
|
6
|
+
from tgclip.utils import console_input_func
|
|
7
|
+
from tgclip.ui import console
|
|
8
|
+
|
|
9
|
+
CONFIG_DIR = Path(user_config_dir("tgclip", ""))
|
|
10
|
+
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
11
|
+
CONFIG_FILE = CONFIG_DIR / "config.json"
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def clear_config():
|
|
15
|
+
if CONFIG_FILE.exists():
|
|
16
|
+
CONFIG_FILE.unlink()
|
|
17
|
+
console.print("[green]Clear config successfully.[/]")
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def load_config() -> dict[str, Any] | None:
|
|
21
|
+
if CONFIG_FILE.exists():
|
|
22
|
+
with CONFIG_FILE.open("r", encoding="utf-8") as f:
|
|
23
|
+
return json.load(f)
|
|
24
|
+
return None
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def save_config(bot_token: str, chat_id: int, name: str | None):
|
|
28
|
+
with CONFIG_FILE.open("w", encoding="utf-8") as f:
|
|
29
|
+
config = {"bot_token": bot_token, "chat_id": chat_id}
|
|
30
|
+
|
|
31
|
+
if name is not None:
|
|
32
|
+
config["name"] = name
|
|
33
|
+
|
|
34
|
+
json.dump(config, f, indent=4)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def setup_name():
|
|
38
|
+
console.print("[bold yellow]⚙ First time setup required[/bold yellow]\n")
|
|
39
|
+
|
|
40
|
+
console.print("[cyan]What should I call you? (default: Friend):[/]")
|
|
41
|
+
name = console_input_func()
|
|
42
|
+
|
|
43
|
+
if name == "":
|
|
44
|
+
console.print("[red]No worrries! I'll call you 'Friend'.[/red]\n")
|
|
45
|
+
return None
|
|
46
|
+
|
|
47
|
+
return name
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def is_config_complete(config: dict[str, Any] | None) -> bool:
|
|
51
|
+
if config is None:
|
|
52
|
+
console.print("Please run 'tgclip init' first.")
|
|
53
|
+
return False
|
|
54
|
+
|
|
55
|
+
return bool(config.get("bot_token")) and bool(config.get("chat_id"))
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
from time import sleep
|
|
2
|
+
import time
|
|
3
|
+
import sys
|
|
4
|
+
import pyperclip
|
|
5
|
+
import typer
|
|
6
|
+
|
|
7
|
+
from tgclip.clipboard import get_text
|
|
8
|
+
from tgclip.ui import console, show_config, welcome_screen
|
|
9
|
+
from tgclip.config import (
|
|
10
|
+
clear_config,
|
|
11
|
+
is_config_complete,
|
|
12
|
+
load_config,
|
|
13
|
+
save_config,
|
|
14
|
+
setup_name,
|
|
15
|
+
)
|
|
16
|
+
from tgclip.telegram import get_user_chat_id, send_message, validate_token
|
|
17
|
+
from tgclip.utils import console_input_func, multiline_input, clear_screen
|
|
18
|
+
|
|
19
|
+
app = typer.Typer(
|
|
20
|
+
add_completion=False, help="Send clipboard content to Telegram instantly."
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@app.command(help="Configur tgclip with your Telegram bot and chat ID.")
|
|
25
|
+
def init():
|
|
26
|
+
with console.status(
|
|
27
|
+
"[bold cyan]Initializing TGClip Engine...[/]", spinner="dots12"
|
|
28
|
+
):
|
|
29
|
+
time.sleep(3)
|
|
30
|
+
|
|
31
|
+
token_attempt = 1
|
|
32
|
+
config = load_config()
|
|
33
|
+
|
|
34
|
+
if not config:
|
|
35
|
+
user_name = setup_name()
|
|
36
|
+
|
|
37
|
+
while True:
|
|
38
|
+
console.print("[cyan]Enter BOT TOKEN:[/]")
|
|
39
|
+
bot_token = console_input_func()
|
|
40
|
+
|
|
41
|
+
sys.stdout.write("\033[F") # Cursor one line upar
|
|
42
|
+
sys.stdout.write("\033[2K") # clear those line
|
|
43
|
+
sys.stdout.flush()
|
|
44
|
+
with console.status("[cyan]Verifying Token....[/cyan]", spinner="dots"):
|
|
45
|
+
is_valid = validate_token(bot_token)
|
|
46
|
+
|
|
47
|
+
if is_valid:
|
|
48
|
+
console.print("[bold green]✓ Token verify successfully[/bold green]\n")
|
|
49
|
+
break
|
|
50
|
+
|
|
51
|
+
if token_attempt == 4:
|
|
52
|
+
console.print(
|
|
53
|
+
"[bold red]Error: Reach max attempt. Try again[/bold red]"
|
|
54
|
+
)
|
|
55
|
+
return
|
|
56
|
+
|
|
57
|
+
console.print("[red]Error: Invalid Bot Token[/red]")
|
|
58
|
+
token_attempt += 1
|
|
59
|
+
|
|
60
|
+
while True:
|
|
61
|
+
chat_id = get_user_chat_id(bot_token)
|
|
62
|
+
|
|
63
|
+
if chat_id:
|
|
64
|
+
save_config(bot_token, chat_id, user_name)
|
|
65
|
+
break
|
|
66
|
+
|
|
67
|
+
console.print("[bold red]Note:[/bold red]")
|
|
68
|
+
sleep(0.2)
|
|
69
|
+
console.print("[red]Open your Telegram bot.[/red]")
|
|
70
|
+
sleep(0.2)
|
|
71
|
+
console.print("[cyan]Send [blue]/start[/blue].[/cyan]")
|
|
72
|
+
sleep(0.2)
|
|
73
|
+
console.input("[green]Press Enter after sending /start...[/green]\n")
|
|
74
|
+
|
|
75
|
+
console.print("[bold green]✓ Configuration saved successfully[/bold green]\n")
|
|
76
|
+
return
|
|
77
|
+
|
|
78
|
+
is_config = is_config_complete(config)
|
|
79
|
+
|
|
80
|
+
if is_config:
|
|
81
|
+
console.print("[bold yellow]All ready setup.[/bold yellow]\n")
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
@app.command(help="Send clipboard text content to Telegram.")
|
|
85
|
+
def send():
|
|
86
|
+
config = load_config()
|
|
87
|
+
|
|
88
|
+
is_config = is_config_complete(config)
|
|
89
|
+
if config is None or is_config is False:
|
|
90
|
+
return
|
|
91
|
+
|
|
92
|
+
text = get_text()
|
|
93
|
+
|
|
94
|
+
if not text.strip():
|
|
95
|
+
console.print("Clipboard is empty.")
|
|
96
|
+
return
|
|
97
|
+
|
|
98
|
+
response = send_message(config, text)
|
|
99
|
+
|
|
100
|
+
if response is None:
|
|
101
|
+
return
|
|
102
|
+
|
|
103
|
+
if not response.ok:
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
message_id = response.json()["result"]["message_id"]
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
@app.command(help="Monitor the clipboard and automatically send new content.")
|
|
110
|
+
def watch():
|
|
111
|
+
config = load_config()
|
|
112
|
+
|
|
113
|
+
is_config = is_config_complete(config)
|
|
114
|
+
if config is None or is_config is False:
|
|
115
|
+
return
|
|
116
|
+
|
|
117
|
+
last_text = None
|
|
118
|
+
|
|
119
|
+
try:
|
|
120
|
+
while True:
|
|
121
|
+
text = get_text()
|
|
122
|
+
|
|
123
|
+
if not text.strip():
|
|
124
|
+
time.sleep(0.5)
|
|
125
|
+
continue
|
|
126
|
+
|
|
127
|
+
if text == last_text:
|
|
128
|
+
time.sleep(0.5)
|
|
129
|
+
continue
|
|
130
|
+
|
|
131
|
+
response = send_message(config, text)
|
|
132
|
+
|
|
133
|
+
last_text = text
|
|
134
|
+
time.sleep(0.5)
|
|
135
|
+
|
|
136
|
+
if response is None:
|
|
137
|
+
return
|
|
138
|
+
|
|
139
|
+
message_id = response.json()["result"]["message_id"]
|
|
140
|
+
|
|
141
|
+
except KeyboardInterrupt:
|
|
142
|
+
console.print("\n[yellow]Stopped watching.[/yellow]")
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
@app.command(help="Start an intractive shell to send multiple messages.")
|
|
146
|
+
def shell():
|
|
147
|
+
config = load_config()
|
|
148
|
+
|
|
149
|
+
is_config = is_config_complete(config)
|
|
150
|
+
if config is None or is_config is False:
|
|
151
|
+
return
|
|
152
|
+
|
|
153
|
+
clear_screen()
|
|
154
|
+
|
|
155
|
+
console.print("[bold green]TGCLIP Shell[/bold green]")
|
|
156
|
+
console.print("Type '/exit' to quit.")
|
|
157
|
+
console.print("Type '/clear' to clear screen.\n")
|
|
158
|
+
|
|
159
|
+
while True:
|
|
160
|
+
try:
|
|
161
|
+
console.print("➤ (Enter empty line to send)")
|
|
162
|
+
|
|
163
|
+
texts = multiline_input(config.get("name", "Friend"))
|
|
164
|
+
if texts == "exit":
|
|
165
|
+
return
|
|
166
|
+
|
|
167
|
+
if not texts:
|
|
168
|
+
continue
|
|
169
|
+
|
|
170
|
+
response = send_message(config, texts)
|
|
171
|
+
|
|
172
|
+
if response is None:
|
|
173
|
+
return
|
|
174
|
+
|
|
175
|
+
message_id = response.json()["result"]["message_id"]
|
|
176
|
+
|
|
177
|
+
except KeyboardInterrupt:
|
|
178
|
+
break
|
|
179
|
+
|
|
180
|
+
|
|
181
|
+
@app.command(help="Display the current tgclip configuration.")
|
|
182
|
+
def config():
|
|
183
|
+
config = load_config()
|
|
184
|
+
|
|
185
|
+
is_config = is_config_complete(config)
|
|
186
|
+
if config is None or is_config is False:
|
|
187
|
+
return
|
|
188
|
+
|
|
189
|
+
show_config(config)
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@app.command(help="Remove the current configuration.")
|
|
193
|
+
def reset():
|
|
194
|
+
config = load_config()
|
|
195
|
+
|
|
196
|
+
is_config = is_config_complete(config)
|
|
197
|
+
if config is None or is_config is False:
|
|
198
|
+
return
|
|
199
|
+
|
|
200
|
+
clear_config()
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
@app.command(help="Check your setup and diagnose configuration or connection issues.")
|
|
204
|
+
def doctor():
|
|
205
|
+
config = load_config()
|
|
206
|
+
|
|
207
|
+
with console.status("[cyan]Cheking config...[/cyan]", spinner="arc"):
|
|
208
|
+
sleep(0.3)
|
|
209
|
+
is_config = is_config_complete(config)
|
|
210
|
+
if config is None or is_config is False:
|
|
211
|
+
return
|
|
212
|
+
|
|
213
|
+
bot_token = config.get("bot_token")
|
|
214
|
+
config_chat_id = config.get("chat_id")
|
|
215
|
+
assert bot_token is not None
|
|
216
|
+
|
|
217
|
+
console.print("[green]✔ Config found[/green]")
|
|
218
|
+
sleep(0.3)
|
|
219
|
+
|
|
220
|
+
with console.status("[cyan]Cheking token...[/cyan]", spinner="arc"):
|
|
221
|
+
isvalid = validate_token(bot_token)
|
|
222
|
+
|
|
223
|
+
if isvalid:
|
|
224
|
+
console.print("[green]✔ Token valid[/green]")
|
|
225
|
+
sleep(0.3)
|
|
226
|
+
|
|
227
|
+
with console.status("[cyan]Cheking chat ID...[/cyan]", spinner="arc"):
|
|
228
|
+
new_chat_id = get_user_chat_id(bot_token)
|
|
229
|
+
|
|
230
|
+
if new_chat_id is not None:
|
|
231
|
+
if config_chat_id == new_chat_id:
|
|
232
|
+
console.print("[green]✔ Chat ID valid[/green]")
|
|
233
|
+
else:
|
|
234
|
+
console.print("[red]✘Chat ID not valid[/red]")
|
|
235
|
+
sleep(0.2)
|
|
236
|
+
|
|
237
|
+
try:
|
|
238
|
+
with console.status("[cyan]Cheking clipboard...[/cyan]", spinner="arc"):
|
|
239
|
+
sleep(0.3)
|
|
240
|
+
pyperclip.paste()
|
|
241
|
+
|
|
242
|
+
console.print("[green]✔ Clipboard working[/green]")
|
|
243
|
+
except Exception:
|
|
244
|
+
console.print("[red]✘ Clipboard not accessible[/red]")
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
@app.callback(invoke_without_command=True)
|
|
248
|
+
def callback(ctx: typer.Context):
|
|
249
|
+
if ctx.invoked_subcommand is None:
|
|
250
|
+
welcome_screen()
|
|
251
|
+
raise typer.Exit()
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
def main():
|
|
255
|
+
app()
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
if __name__ == "__main__":
|
|
259
|
+
main()
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import requests
|
|
2
|
+
import time
|
|
3
|
+
|
|
4
|
+
from tgclip.ui import console
|
|
5
|
+
from typing import Any
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def telegram_request(
|
|
9
|
+
method: str, url: str, payload: dict | None = None
|
|
10
|
+
) -> requests.Response | None:
|
|
11
|
+
try:
|
|
12
|
+
if method == "get":
|
|
13
|
+
response = requests.get(url)
|
|
14
|
+
return response
|
|
15
|
+
if method == "post":
|
|
16
|
+
response = requests.post(url=url, data=payload)
|
|
17
|
+
return response
|
|
18
|
+
|
|
19
|
+
except requests.exceptions.ConnectionError:
|
|
20
|
+
console.print("[bold red]✘ No internet connection.[/bold red]")
|
|
21
|
+
return None
|
|
22
|
+
except requests.exceptions.Timeout:
|
|
23
|
+
console.print("[bold red]✘ Request time out. Please try again.[/bold red]")
|
|
24
|
+
return None
|
|
25
|
+
except requests.RequestException as e:
|
|
26
|
+
console.print(f"[bold red]✘ Network error: {e} [/bold red]")
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def send_message(config: dict[str, Any], text) -> requests.Response | None:
|
|
31
|
+
bot_token = config.get("bot_token")
|
|
32
|
+
chat_id = config.get("chat_id")
|
|
33
|
+
|
|
34
|
+
url = f"https://api.telegram.org/bot{bot_token}/sendMessage"
|
|
35
|
+
|
|
36
|
+
with console.status("[cyan]Sending...[/cyan]", spinner="dots"):
|
|
37
|
+
response = telegram_request(
|
|
38
|
+
method="post", payload={"chat_id": chat_id, "text": text}, url=url
|
|
39
|
+
)
|
|
40
|
+
time.sleep(0.3)
|
|
41
|
+
|
|
42
|
+
if response and response.ok:
|
|
43
|
+
console.print(" " * 30, end="\r") # clear line
|
|
44
|
+
console.print("[green]✓ Sent[/green]")
|
|
45
|
+
else:
|
|
46
|
+
console.print("[red]✕ Fail[/red]")
|
|
47
|
+
|
|
48
|
+
return response
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def delete_message_later(config: dict[str, Any], message_id: int, delay=60):
|
|
52
|
+
bot_token = config.get("bot_token")
|
|
53
|
+
chat_id = config.get("chat_id")
|
|
54
|
+
|
|
55
|
+
time.sleep(delay)
|
|
56
|
+
|
|
57
|
+
url = f"https://api.telegram.org/bot{bot_token}/deleteMessage"
|
|
58
|
+
|
|
59
|
+
telegram_request(
|
|
60
|
+
method="post",
|
|
61
|
+
payload={
|
|
62
|
+
"chat_id": chat_id,
|
|
63
|
+
"message_id": message_id,
|
|
64
|
+
},
|
|
65
|
+
url=url,
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
def get_user_chat_id(bot_token: str):
|
|
70
|
+
url = f"https://api.telegram.org/bot{bot_token}/getUpdates"
|
|
71
|
+
response = telegram_request(method="get", url=url)
|
|
72
|
+
|
|
73
|
+
if response and response.ok:
|
|
74
|
+
updates = response.json().get("result", [])
|
|
75
|
+
return updates[-1]["message"]["chat"]["id"] if updates else None
|
|
76
|
+
|
|
77
|
+
return None
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def validate_token(bot_token: str):
|
|
81
|
+
url = f"https://api.telegram.org/bot{bot_token}/getMe"
|
|
82
|
+
|
|
83
|
+
response = telegram_request(method="get", url=url)
|
|
84
|
+
|
|
85
|
+
if response and response.ok:
|
|
86
|
+
data = response.json()
|
|
87
|
+
return data.get("ok", False)
|
|
88
|
+
|
|
89
|
+
return False
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from rich.align import Align
|
|
2
|
+
from rich.table import Table
|
|
3
|
+
from rich.console import Console
|
|
4
|
+
from rich.panel import Panel
|
|
5
|
+
from rich import box
|
|
6
|
+
from time import sleep
|
|
7
|
+
|
|
8
|
+
from rich.text import Text
|
|
9
|
+
|
|
10
|
+
console = Console()
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# show config
|
|
14
|
+
def show_config(config):
|
|
15
|
+
table = Table(
|
|
16
|
+
box=box.SIMPLE,
|
|
17
|
+
show_header=False,
|
|
18
|
+
pad_edge=False,
|
|
19
|
+
expand=True,
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
table.add_column("Key", style="bold cyan", justify="left")
|
|
23
|
+
table.add_column("Value", style="white")
|
|
24
|
+
|
|
25
|
+
table.add_row("Name", config.get("name", "[dim]not set[/dim]"))
|
|
26
|
+
table.add_row("Chat ID", str(config.get("chat_id", "[dim]not set[/dim]")))
|
|
27
|
+
table.add_row("Auto Delete", config.get("auto_delete", "disabled"))
|
|
28
|
+
table.add_row("Delete After", config.get("delete_after", "30s"))
|
|
29
|
+
table.add_row("Version", config.get("version", "0.1.0"))
|
|
30
|
+
|
|
31
|
+
panel = Panel(
|
|
32
|
+
table,
|
|
33
|
+
title="⚙ TGClip System Config",
|
|
34
|
+
title_align="center",
|
|
35
|
+
border_style="bright_blue",
|
|
36
|
+
box=box.ROUNDED,
|
|
37
|
+
padding=(1, 2),
|
|
38
|
+
expand=False,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
console.print(panel)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# Welcome Screen
|
|
45
|
+
def welcome_screen():
|
|
46
|
+
with console.status(
|
|
47
|
+
"[bold bright_cyan]⚡ Initializing TGClip...[/bold bright_cyan]",
|
|
48
|
+
spinner="aesthetic",
|
|
49
|
+
):
|
|
50
|
+
sleep(1.5)
|
|
51
|
+
header = Text("TGClip", style="bold bright_magenta")
|
|
52
|
+
|
|
53
|
+
body = (
|
|
54
|
+
"[bold white]Welcome to[/bold white] [bold bright_red]TGClip[/bold bright_red] CLI Tool 🌻\n\n"
|
|
55
|
+
"[bold white]Telegram Clipboard CLI[/bold white]\n"
|
|
56
|
+
"[dim]Fast • Minimal • Smart Automation Tool[/dim]\n\n"
|
|
57
|
+
"[cyan]➤ Version:[/cyan] [green]1.0.0[/green]\n"
|
|
58
|
+
"[cyan]➤ Status:[/cyan] [green]Ready[/green]\n"
|
|
59
|
+
"[cyan]➤ Mode:[/cyan] [magenta]Interactive Shell[/magenta]\n\n"
|
|
60
|
+
"[dim]Commands:[/dim]\n"
|
|
61
|
+
"[yellow]--help[/yellow] Show all available commands\n\n"
|
|
62
|
+
"[dim]Tip:[/dim]\n"
|
|
63
|
+
"Run [green]tgclip --help[/green] to start using TGClip\n\n"
|
|
64
|
+
"[dim]------------------------------------------------[/dim]\n"
|
|
65
|
+
"[dim]Devloped by CyberLeafy 🕊️[/dim]\n"
|
|
66
|
+
"[dim]Version 0.1.0 [/dim]"
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
panel = Panel(
|
|
70
|
+
Align.center(body),
|
|
71
|
+
title=header,
|
|
72
|
+
title_align="center",
|
|
73
|
+
border_style="magenta",
|
|
74
|
+
box=box.ROUNDED,
|
|
75
|
+
padding=(1, 4),
|
|
76
|
+
expand=False,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
console.print(panel)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
from tgclip.ui import console
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def console_input_func():
|
|
6
|
+
return console.input("[bold green]➤ [/bold green]").strip()
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def clear_screen():
|
|
10
|
+
os.system("cls" if os.name == "nt" else "clear")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def multiline_input(name: str):
|
|
14
|
+
lines = []
|
|
15
|
+
while True:
|
|
16
|
+
line = input()
|
|
17
|
+
|
|
18
|
+
if line.lower() == "/exit":
|
|
19
|
+
console.print(f"\nGoodbye 👋 {name}!")
|
|
20
|
+
return "exit"
|
|
21
|
+
|
|
22
|
+
if line.lower() == "/clear":
|
|
23
|
+
clear_screen()
|
|
24
|
+
console.print("[bold green]TGCLIP Shell[/bold green]")
|
|
25
|
+
console.print("Type '/exit' to quit.")
|
|
26
|
+
console.print("Type '/clear' to clear screen.\n")
|
|
27
|
+
console.print("➤ (Enter empty line to send)")
|
|
28
|
+
continue
|
|
29
|
+
|
|
30
|
+
if line.startswith("/"):
|
|
31
|
+
console.print("[red]Invalid command[/red]")
|
|
32
|
+
continue
|
|
33
|
+
|
|
34
|
+
if line == "":
|
|
35
|
+
break
|
|
36
|
+
lines.append(line)
|
|
37
|
+
|
|
38
|
+
return "\n".join(lines)
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tgclip
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Send clipboard content to Telegram instantly.
|
|
5
|
+
Author: CyberLeafy
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: telegram,clipboard,cli,terminal,python
|
|
8
|
+
Requires-Python: >=3.14
|
|
9
|
+
Description-Content-Type: text/markdown
|
|
10
|
+
License-File: LICENSE
|
|
11
|
+
Requires-Dist: platformdirs>=4.10.0
|
|
12
|
+
Requires-Dist: pyperclip>=1.11.0
|
|
13
|
+
Requires-Dist: requests>=2.34.2
|
|
14
|
+
Requires-Dist: rich>=15.0.0
|
|
15
|
+
Requires-Dist: typer>=0.26.8
|
|
16
|
+
Dynamic: license-file
|
|
17
|
+
|
|
18
|
+
<div align="center">
|
|
19
|
+
|
|
20
|
+
# 📋 TGCLIP
|
|
21
|
+
|
|
22
|
+
### Instantly send clipboard content or text from your computer to Telegram.
|
|
23
|
+
|
|
24
|
+
[](https://pypi.org/project/tgclip/)
|
|
25
|
+
[](https://www.python.org/)
|
|
26
|
+
[](#-license)
|
|
27
|
+
[](https://core.telegram.org/bots)
|
|
28
|
+
|
|
29
|
+
A lightweight CLI that moves text, code, links, and commands from your desktop straight to Telegram — built for developers, students, and anyone who lives between a laptop and a phone.
|
|
30
|
+
|
|
31
|
+
</div>
|
|
32
|
+
|
|
33
|
+
<br>
|
|
34
|
+
|
|
35
|
+
## Table of Contents
|
|
36
|
+
|
|
37
|
+
- [Features](#-features)
|
|
38
|
+
- [Installation](#-installation)
|
|
39
|
+
- [Prerequisites](#-prerequisites)
|
|
40
|
+
- [Quick Start](#-quick-start)
|
|
41
|
+
- [Commands](#-commands)
|
|
42
|
+
- [Workflow](#-workflow)
|
|
43
|
+
- [Use Cases](#-use-cases)
|
|
44
|
+
- [Privacy](#-privacy)
|
|
45
|
+
- [Troubleshooting](#-troubleshooting)
|
|
46
|
+
- [Requirements](#-requirements)
|
|
47
|
+
- [Issues](#-issues)
|
|
48
|
+
- [License](#-license)
|
|
49
|
+
|
|
50
|
+
<br>
|
|
51
|
+
|
|
52
|
+
## ⚡ Features
|
|
53
|
+
|
|
54
|
+
<table>
|
|
55
|
+
<tr><td width="40">🚀</td><td>Simple one-time setup</td></tr>
|
|
56
|
+
<tr><td>📋</td><td>Send clipboard content instantly</td></tr>
|
|
57
|
+
<tr><td>✍️</td><td>Send custom text directly from the terminal</td></tr>
|
|
58
|
+
<tr><td>👀</td><td>Clipboard watch mode</td></tr>
|
|
59
|
+
<tr><td>💻</td><td>Interactive shell mode</td></tr>
|
|
60
|
+
<tr><td>⚙️</td><td>Easy configuration management</td></tr>
|
|
61
|
+
<tr><td>🩺</td><td>Built-in diagnostics with <code>doctor</code></td></tr>
|
|
62
|
+
<tr><td>🔄</td><td>Reset configuration anytime</td></tr>
|
|
63
|
+
<tr><td>🎨</td><td>Clean, colorful terminal UI powered by Rich</td></tr>
|
|
64
|
+
</table>
|
|
65
|
+
|
|
66
|
+
<br>
|
|
67
|
+
|
|
68
|
+
## 📦 Installation
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
pip install tgclip
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Verify it worked:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
tgclip
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
<br>
|
|
81
|
+
|
|
82
|
+
## ✅ Prerequisites
|
|
83
|
+
|
|
84
|
+
| Requirement | Details |
|
|
85
|
+
|---|---|
|
|
86
|
+
| Telegram account | Any personal account |
|
|
87
|
+
| Telegram Bot | Created via [@BotFather](https://t.me/BotFather) |
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
<br>
|
|
91
|
+
|
|
92
|
+
## 🚀 Quick Start
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
tgclip init
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
You'll be prompted for:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
① Your name
|
|
102
|
+
② Telegram Bot Token
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
> 💾 Configuration is stored **locally** on your machine — nothing is uploaded anywhere else.
|
|
106
|
+
|
|
107
|
+
<br>
|
|
108
|
+
|
|
109
|
+
## 🛠 Commands
|
|
110
|
+
|
|
111
|
+
<details open>
|
|
112
|
+
<summary><b><code>tgclip init</code></b> — Initialize</summary>
|
|
113
|
+
<br>
|
|
114
|
+
|
|
115
|
+
Configure TGCLIP for first-time use.
|
|
116
|
+
</details>
|
|
117
|
+
|
|
118
|
+
<details open>
|
|
119
|
+
<summary><b><code>tgclip send</code></b> — Send</summary>
|
|
120
|
+
<br>
|
|
121
|
+
|
|
122
|
+
Send the current clipboard content to Telegram.
|
|
123
|
+
</details>
|
|
124
|
+
|
|
125
|
+
<details open>
|
|
126
|
+
<summary><b><code>tgclip watch</code></b> — Watch</summary>
|
|
127
|
+
<br>
|
|
128
|
+
|
|
129
|
+
Continuously monitor the clipboard and auto-send anything newly copied.
|
|
130
|
+
Stop with `Ctrl + C`.
|
|
131
|
+
</details>
|
|
132
|
+
|
|
133
|
+
<details open>
|
|
134
|
+
<summary><b><code>tgclip shell</code></b> — Shell</summary>
|
|
135
|
+
<br>
|
|
136
|
+
|
|
137
|
+
Launch an interactive shell for sending multiple messages without restarting the command.
|
|
138
|
+
Exit with `/exit` or `Ctrl + C`.
|
|
139
|
+
</details>
|
|
140
|
+
|
|
141
|
+
<details open>
|
|
142
|
+
<summary><b><code>tgclip config</code></b> — Configuration</summary>
|
|
143
|
+
<br>
|
|
144
|
+
|
|
145
|
+
Display your current configuration.
|
|
146
|
+
</details>
|
|
147
|
+
|
|
148
|
+
<details open>
|
|
149
|
+
<summary><b><code>tgclip doctor</code></b> — Doctor</summary>
|
|
150
|
+
<br>
|
|
151
|
+
|
|
152
|
+
Runs a full health check:
|
|
153
|
+
|
|
154
|
+
- ☑ Configuration
|
|
155
|
+
- ☑ Clipboard access
|
|
156
|
+
- ☑ Internet connectivity
|
|
157
|
+
- ☑ Telegram API access
|
|
158
|
+
- ☑ Bot token
|
|
159
|
+
- ☑ Chat ID
|
|
160
|
+
</details>
|
|
161
|
+
|
|
162
|
+
<details open>
|
|
163
|
+
<summary><b><code>tgclip reset</code></b> — Reset</summary>
|
|
164
|
+
<br>
|
|
165
|
+
|
|
166
|
+
Wipes the current configuration so you can start fresh.
|
|
167
|
+
</details>
|
|
168
|
+
|
|
169
|
+
<br>
|
|
170
|
+
|
|
171
|
+
## 🔁 Workflow
|
|
172
|
+
|
|
173
|
+
```mermaid
|
|
174
|
+
flowchart LR
|
|
175
|
+
A[📄 Copy text] --> B[tgclip send]
|
|
176
|
+
B --> C[✈️ Telegram]
|
|
177
|
+
C --> D[📱 Open on phone]
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
<br>
|
|
181
|
+
|
|
182
|
+
## 💡 Use Cases
|
|
183
|
+
|
|
184
|
+
- 🧩 Send code snippets to your phone
|
|
185
|
+
- 🔗 Transfer commands between devices
|
|
186
|
+
- 📝 Save temporary notes
|
|
187
|
+
- 🌐 Share links instantly
|
|
188
|
+
- 📤 Move terminal output
|
|
189
|
+
- 🔄 Continue work from mobile
|
|
190
|
+
|
|
191
|
+
<br>
|
|
192
|
+
|
|
193
|
+
## 🔒 Privacy
|
|
194
|
+
|
|
195
|
+
TGCLIP talks **directly** to the Telegram Bot API — nothing else is in the loop.
|
|
196
|
+
|
|
197
|
+
- ✔ Configuration stays on your local machine
|
|
198
|
+
- ✔ No external servers, no telemetry, no middleman
|
|
199
|
+
|
|
200
|
+
<br>
|
|
201
|
+
|
|
202
|
+
## 🧰 Troubleshooting
|
|
203
|
+
|
|
204
|
+
| Problem | Fix |
|
|
205
|
+
|---|---|
|
|
206
|
+
| Something's not working | `tgclip doctor` |
|
|
207
|
+
| Need to start over | `tgclip reset` → `tgclip init` |
|
|
208
|
+
| Forgot a command | `tgclip --help` |
|
|
209
|
+
|
|
210
|
+
<br>
|
|
211
|
+
|
|
212
|
+
## 📋 Requirements
|
|
213
|
+
|
|
214
|
+
- Python **3.10+**
|
|
215
|
+
- A Telegram Bot
|
|
216
|
+
- An internet connection
|
|
217
|
+
|
|
218
|
+
<br>
|
|
219
|
+
|
|
220
|
+
## 🐞 Issues
|
|
221
|
+
Found a bug or have a feature request? Please open an issue on Github.
|
|
222
|
+
|
|
223
|
+
<br>
|
|
224
|
+
|
|
225
|
+
## 📄 License
|
|
226
|
+
Released under the **MIT License**.
|
|
227
|
+
|
|
228
|
+
<br>
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
<div align="center">
|
|
232
|
+
|
|
233
|
+
**Developed by CyberLeafy**
|
|
234
|
+
|
|
235
|
+
*TGCLIP — Fast. Simple. Clipboard to Telegram.* 📋➡️📱
|
|
236
|
+
|
|
237
|
+
</div>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
src/tgclip/__init__.py
|
|
5
|
+
src/tgclip/__main__.py
|
|
6
|
+
src/tgclip/clipboard.py
|
|
7
|
+
src/tgclip/config.py
|
|
8
|
+
src/tgclip/main.py
|
|
9
|
+
src/tgclip/telegram.py
|
|
10
|
+
src/tgclip/ui.py
|
|
11
|
+
src/tgclip/utils.py
|
|
12
|
+
src/tgclip.egg-info/PKG-INFO
|
|
13
|
+
src/tgclip.egg-info/SOURCES.txt
|
|
14
|
+
src/tgclip.egg-info/dependency_links.txt
|
|
15
|
+
src/tgclip.egg-info/entry_points.txt
|
|
16
|
+
src/tgclip.egg-info/requires.txt
|
|
17
|
+
src/tgclip.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
tgclip
|