telepress 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.
- telepress-0.1.0/LICENSE +21 -0
- telepress-0.1.0/PKG-INFO +156 -0
- telepress-0.1.0/README.md +109 -0
- telepress-0.1.0/setup.cfg +4 -0
- telepress-0.1.0/setup.py +55 -0
- telepress-0.1.0/src/telepress/__init__.py +116 -0
- telepress-0.1.0/src/telepress/auth.py +57 -0
- telepress-0.1.0/src/telepress/cli.py +26 -0
- telepress-0.1.0/src/telepress/converter.py +36 -0
- telepress-0.1.0/src/telepress/core.py +329 -0
- telepress-0.1.0/src/telepress/exceptions.py +27 -0
- telepress-0.1.0/src/telepress/interfaces.py +38 -0
- telepress-0.1.0/src/telepress/server.py +132 -0
- telepress-0.1.0/src/telepress/uploader.py +43 -0
- telepress-0.1.0/src/telepress/utils.py +67 -0
- telepress-0.1.0/src/telepress.egg-info/PKG-INFO +156 -0
- telepress-0.1.0/src/telepress.egg-info/SOURCES.txt +27 -0
- telepress-0.1.0/src/telepress.egg-info/dependency_links.txt +1 -0
- telepress-0.1.0/src/telepress.egg-info/entry_points.txt +3 -0
- telepress-0.1.0/src/telepress.egg-info/requires.txt +13 -0
- telepress-0.1.0/src/telepress.egg-info/top_level.txt +1 -0
- telepress-0.1.0/tests/test_auth.py +121 -0
- telepress-0.1.0/tests/test_cli.py +162 -0
- telepress-0.1.0/tests/test_converter.py +177 -0
- telepress-0.1.0/tests/test_core.py +523 -0
- telepress-0.1.0/tests/test_exceptions.py +155 -0
- telepress-0.1.0/tests/test_server.py +251 -0
- telepress-0.1.0/tests/test_uploader.py +161 -0
- telepress-0.1.0/tests/test_utils.py +311 -0
telepress-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 zoidberg-xgd
|
|
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.
|
telepress-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: telepress
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Publish Markdown, images and zip archives to Telegraph
|
|
5
|
+
Home-page: https://github.com/zoidberg-xgd/telepress
|
|
6
|
+
Author: zoidberg-xgd
|
|
7
|
+
Author-email:
|
|
8
|
+
Project-URL: Bug Reports, https://github.com/zoidberg-xgd/telepress/issues
|
|
9
|
+
Project-URL: Source, https://github.com/zoidberg-xgd/telepress
|
|
10
|
+
Keywords: telegraph,markdown,publishing,gallery
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Requires-Python: >=3.7
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: telegraph
|
|
25
|
+
Requires-Dist: markdown
|
|
26
|
+
Requires-Dist: requests
|
|
27
|
+
Provides-Extra: api
|
|
28
|
+
Requires-Dist: fastapi; extra == "api"
|
|
29
|
+
Requires-Dist: uvicorn; extra == "api"
|
|
30
|
+
Requires-Dist: python-multipart; extra == "api"
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
34
|
+
Requires-Dist: httpx; extra == "dev"
|
|
35
|
+
Dynamic: author
|
|
36
|
+
Dynamic: classifier
|
|
37
|
+
Dynamic: description
|
|
38
|
+
Dynamic: description-content-type
|
|
39
|
+
Dynamic: home-page
|
|
40
|
+
Dynamic: keywords
|
|
41
|
+
Dynamic: license-file
|
|
42
|
+
Dynamic: project-url
|
|
43
|
+
Dynamic: provides-extra
|
|
44
|
+
Dynamic: requires-dist
|
|
45
|
+
Dynamic: requires-python
|
|
46
|
+
Dynamic: summary
|
|
47
|
+
|
|
48
|
+
# TelePress
|
|
49
|
+
|
|
50
|
+
[中文文档](README_CN.md)
|
|
51
|
+
|
|
52
|
+
Publish Markdown, images and zip archives to [Telegraph](https://telegra.ph). Handles large files by auto-splitting into multiple linked pages.
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pip install telepress
|
|
58
|
+
|
|
59
|
+
# with REST API
|
|
60
|
+
pip install telepress[api]
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Usage
|
|
64
|
+
|
|
65
|
+
```python
|
|
66
|
+
from telepress import publish, publish_text
|
|
67
|
+
|
|
68
|
+
url = publish("article.md")
|
|
69
|
+
url = publish_text("# Hello\n\nWorld!", title="Test")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
CLI:
|
|
73
|
+
```bash
|
|
74
|
+
telepress article.md --title "My Post"
|
|
75
|
+
telepress photos.zip --title "Album"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
REST API:
|
|
79
|
+
```bash
|
|
80
|
+
telepress-server --port 8000
|
|
81
|
+
|
|
82
|
+
curl -X POST localhost:8000/publish/text \
|
|
83
|
+
-H "Content-Type: application/json" \
|
|
84
|
+
-d '{"content": "# Title\n\nBody", "title": "Test"}'
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## How it works
|
|
88
|
+
|
|
89
|
+
Text files are converted to Telegraph format (Markdown supported). Large content is split at ~40KB boundaries into multiple pages with prev/next navigation.
|
|
90
|
+
|
|
91
|
+
Zip files are treated as image galleries. Images are sorted naturally (1, 2, 10 not 1, 10, 2) and paginated at 100 per page.
|
|
92
|
+
|
|
93
|
+
Token is auto-created on first run and saved to `~/.telegraph_token`.
|
|
94
|
+
|
|
95
|
+
## Limits
|
|
96
|
+
|
|
97
|
+
- 100MB max file size
|
|
98
|
+
- 100 pages max (~4M chars text, or 5000 images)
|
|
99
|
+
- 5MB per image (Telegraph limit)
|
|
100
|
+
|
|
101
|
+
Supported: `.txt` `.md` `.markdown` `.rst` `.jpg` `.png` `.gif` `.webp` `.zip`
|
|
102
|
+
|
|
103
|
+
Not supported: PDF, DOCX (convert first)
|
|
104
|
+
|
|
105
|
+
## Project structure
|
|
106
|
+
|
|
107
|
+
```
|
|
108
|
+
telepress/
|
|
109
|
+
├── core.py # TelegraphPublisher
|
|
110
|
+
├── auth.py # token management
|
|
111
|
+
├── converter.py # markdown to telegraph nodes
|
|
112
|
+
├── uploader.py # image upload with retry
|
|
113
|
+
├── server.py # FastAPI service
|
|
114
|
+
└── cli.py # command line
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Error handling
|
|
118
|
+
|
|
119
|
+
```python
|
|
120
|
+
from telepress import publish, ValidationError, TelePressError
|
|
121
|
+
|
|
122
|
+
try:
|
|
123
|
+
url = publish("file.md")
|
|
124
|
+
except ValidationError as e:
|
|
125
|
+
# bad input: wrong format, too large, etc
|
|
126
|
+
print(e)
|
|
127
|
+
except TelePressError as e:
|
|
128
|
+
# other errors: upload failed, auth failed, etc
|
|
129
|
+
print(e)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## Integration
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
# Flask
|
|
136
|
+
@app.route('/publish', methods=['POST'])
|
|
137
|
+
def api_publish():
|
|
138
|
+
url = publish_text(request.json['content'], title=request.json['title'])
|
|
139
|
+
return {'url': url}
|
|
140
|
+
|
|
141
|
+
# async
|
|
142
|
+
async def async_publish(content, title):
|
|
143
|
+
return await asyncio.to_thread(publish_text, content, title)
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Dev
|
|
147
|
+
|
|
148
|
+
```bash
|
|
149
|
+
git clone https://github.com/zoidberg-xgd/telepress
|
|
150
|
+
cd telepress && pip install -e .[dev]
|
|
151
|
+
pytest tests/ -v
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
## License
|
|
155
|
+
|
|
156
|
+
MIT
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# TelePress
|
|
2
|
+
|
|
3
|
+
[中文文档](README_CN.md)
|
|
4
|
+
|
|
5
|
+
Publish Markdown, images and zip archives to [Telegraph](https://telegra.ph). Handles large files by auto-splitting into multiple linked pages.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pip install telepress
|
|
11
|
+
|
|
12
|
+
# with REST API
|
|
13
|
+
pip install telepress[api]
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Usage
|
|
17
|
+
|
|
18
|
+
```python
|
|
19
|
+
from telepress import publish, publish_text
|
|
20
|
+
|
|
21
|
+
url = publish("article.md")
|
|
22
|
+
url = publish_text("# Hello\n\nWorld!", title="Test")
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
CLI:
|
|
26
|
+
```bash
|
|
27
|
+
telepress article.md --title "My Post"
|
|
28
|
+
telepress photos.zip --title "Album"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
REST API:
|
|
32
|
+
```bash
|
|
33
|
+
telepress-server --port 8000
|
|
34
|
+
|
|
35
|
+
curl -X POST localhost:8000/publish/text \
|
|
36
|
+
-H "Content-Type: application/json" \
|
|
37
|
+
-d '{"content": "# Title\n\nBody", "title": "Test"}'
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## How it works
|
|
41
|
+
|
|
42
|
+
Text files are converted to Telegraph format (Markdown supported). Large content is split at ~40KB boundaries into multiple pages with prev/next navigation.
|
|
43
|
+
|
|
44
|
+
Zip files are treated as image galleries. Images are sorted naturally (1, 2, 10 not 1, 10, 2) and paginated at 100 per page.
|
|
45
|
+
|
|
46
|
+
Token is auto-created on first run and saved to `~/.telegraph_token`.
|
|
47
|
+
|
|
48
|
+
## Limits
|
|
49
|
+
|
|
50
|
+
- 100MB max file size
|
|
51
|
+
- 100 pages max (~4M chars text, or 5000 images)
|
|
52
|
+
- 5MB per image (Telegraph limit)
|
|
53
|
+
|
|
54
|
+
Supported: `.txt` `.md` `.markdown` `.rst` `.jpg` `.png` `.gif` `.webp` `.zip`
|
|
55
|
+
|
|
56
|
+
Not supported: PDF, DOCX (convert first)
|
|
57
|
+
|
|
58
|
+
## Project structure
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
telepress/
|
|
62
|
+
├── core.py # TelegraphPublisher
|
|
63
|
+
├── auth.py # token management
|
|
64
|
+
├── converter.py # markdown to telegraph nodes
|
|
65
|
+
├── uploader.py # image upload with retry
|
|
66
|
+
├── server.py # FastAPI service
|
|
67
|
+
└── cli.py # command line
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Error handling
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
from telepress import publish, ValidationError, TelePressError
|
|
74
|
+
|
|
75
|
+
try:
|
|
76
|
+
url = publish("file.md")
|
|
77
|
+
except ValidationError as e:
|
|
78
|
+
# bad input: wrong format, too large, etc
|
|
79
|
+
print(e)
|
|
80
|
+
except TelePressError as e:
|
|
81
|
+
# other errors: upload failed, auth failed, etc
|
|
82
|
+
print(e)
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
## Integration
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
# Flask
|
|
89
|
+
@app.route('/publish', methods=['POST'])
|
|
90
|
+
def api_publish():
|
|
91
|
+
url = publish_text(request.json['content'], title=request.json['title'])
|
|
92
|
+
return {'url': url}
|
|
93
|
+
|
|
94
|
+
# async
|
|
95
|
+
async def async_publish(content, title):
|
|
96
|
+
return await asyncio.to_thread(publish_text, content, title)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
## Dev
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
git clone https://github.com/zoidberg-xgd/telepress
|
|
103
|
+
cd telepress && pip install -e .[dev]
|
|
104
|
+
pytest tests/ -v
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## License
|
|
108
|
+
|
|
109
|
+
MIT
|
telepress-0.1.0/setup.py
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from setuptools import setup, find_packages
|
|
2
|
+
|
|
3
|
+
setup(
|
|
4
|
+
name="telepress",
|
|
5
|
+
version="0.1.0",
|
|
6
|
+
package_dir={"": "src"},
|
|
7
|
+
packages=find_packages(where="src"),
|
|
8
|
+
install_requires=[
|
|
9
|
+
"telegraph",
|
|
10
|
+
"markdown",
|
|
11
|
+
"requests"
|
|
12
|
+
],
|
|
13
|
+
extras_require={
|
|
14
|
+
"api": [
|
|
15
|
+
"fastapi",
|
|
16
|
+
"uvicorn",
|
|
17
|
+
"python-multipart"
|
|
18
|
+
],
|
|
19
|
+
"dev": [
|
|
20
|
+
"pytest",
|
|
21
|
+
"pytest-cov",
|
|
22
|
+
"httpx" # For FastAPI TestClient
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
entry_points={
|
|
26
|
+
'console_scripts': [
|
|
27
|
+
'telepress=telepress.cli:main',
|
|
28
|
+
'telepress-server=telepress.server:main',
|
|
29
|
+
],
|
|
30
|
+
},
|
|
31
|
+
author="zoidberg-xgd",
|
|
32
|
+
author_email="",
|
|
33
|
+
description="Publish Markdown, images and zip archives to Telegraph",
|
|
34
|
+
long_description=open("README.md").read(),
|
|
35
|
+
long_description_content_type="text/markdown",
|
|
36
|
+
python_requires=">=3.7",
|
|
37
|
+
classifiers=[
|
|
38
|
+
"Development Status :: 4 - Beta",
|
|
39
|
+
"Intended Audience :: Developers",
|
|
40
|
+
"License :: OSI Approved :: MIT License",
|
|
41
|
+
"Programming Language :: Python :: 3",
|
|
42
|
+
"Programming Language :: Python :: 3.7",
|
|
43
|
+
"Programming Language :: Python :: 3.8",
|
|
44
|
+
"Programming Language :: Python :: 3.9",
|
|
45
|
+
"Programming Language :: Python :: 3.10",
|
|
46
|
+
"Programming Language :: Python :: 3.11",
|
|
47
|
+
"Programming Language :: Python :: 3.12",
|
|
48
|
+
],
|
|
49
|
+
url="https://github.com/zoidberg-xgd/telepress",
|
|
50
|
+
project_urls={
|
|
51
|
+
"Bug Reports": "https://github.com/zoidberg-xgd/telepress/issues",
|
|
52
|
+
"Source": "https://github.com/zoidberg-xgd/telepress",
|
|
53
|
+
},
|
|
54
|
+
keywords=["telegraph", "markdown", "publishing", "gallery"],
|
|
55
|
+
)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""
|
|
2
|
+
TelePress - Publish content to Telegraph easily.
|
|
3
|
+
|
|
4
|
+
Basic usage:
|
|
5
|
+
>>> from telepress import publish, TelegraphPublisher
|
|
6
|
+
>>>
|
|
7
|
+
>>> # Quick publish (one-liner)
|
|
8
|
+
>>> url = publish("article.md", title="My Article")
|
|
9
|
+
>>>
|
|
10
|
+
>>> # Or use the class for more control
|
|
11
|
+
>>> publisher = TelegraphPublisher()
|
|
12
|
+
>>> url = publisher.publish("article.md")
|
|
13
|
+
>>> url = publisher.publish_text("# Hello\n\nWorld!", title="Test")
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from .core import TelegraphPublisher
|
|
17
|
+
from .exceptions import (
|
|
18
|
+
TelePressError,
|
|
19
|
+
ValidationError,
|
|
20
|
+
UploadError,
|
|
21
|
+
AuthenticationError,
|
|
22
|
+
SecurityError,
|
|
23
|
+
DependencyError,
|
|
24
|
+
ConversionError
|
|
25
|
+
)
|
|
26
|
+
from .utils import (
|
|
27
|
+
MAX_FILE_SIZE,
|
|
28
|
+
MAX_PAGES,
|
|
29
|
+
MAX_TOTAL_IMAGES,
|
|
30
|
+
MAX_IMAGES_PER_PAGE,
|
|
31
|
+
ALLOWED_TEXT_EXTENSIONS,
|
|
32
|
+
ALLOWED_IMAGE_EXTENSIONS,
|
|
33
|
+
ALLOWED_ARCHIVE_EXTENSIONS
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
__version__ = "0.1.0"
|
|
37
|
+
__all__ = [
|
|
38
|
+
# Main class
|
|
39
|
+
'TelegraphPublisher',
|
|
40
|
+
|
|
41
|
+
# Convenience function
|
|
42
|
+
'publish',
|
|
43
|
+
'publish_text',
|
|
44
|
+
|
|
45
|
+
# Exceptions
|
|
46
|
+
'TelePressError',
|
|
47
|
+
'ValidationError',
|
|
48
|
+
'UploadError',
|
|
49
|
+
'AuthenticationError',
|
|
50
|
+
'SecurityError',
|
|
51
|
+
'DependencyError',
|
|
52
|
+
'ConversionError',
|
|
53
|
+
|
|
54
|
+
# Constants
|
|
55
|
+
'MAX_FILE_SIZE',
|
|
56
|
+
'MAX_PAGES',
|
|
57
|
+
'MAX_TOTAL_IMAGES',
|
|
58
|
+
'MAX_IMAGES_PER_PAGE',
|
|
59
|
+
'ALLOWED_TEXT_EXTENSIONS',
|
|
60
|
+
'ALLOWED_IMAGE_EXTENSIONS',
|
|
61
|
+
'ALLOWED_ARCHIVE_EXTENSIONS',
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
# Singleton publisher for convenience functions
|
|
65
|
+
_default_publisher = None
|
|
66
|
+
|
|
67
|
+
def _get_publisher(token=None):
|
|
68
|
+
"""Get or create default publisher instance."""
|
|
69
|
+
global _default_publisher
|
|
70
|
+
if token:
|
|
71
|
+
return TelegraphPublisher(token=token)
|
|
72
|
+
if _default_publisher is None:
|
|
73
|
+
_default_publisher = TelegraphPublisher()
|
|
74
|
+
return _default_publisher
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def publish(file_path: str, title: str = None, token: str = None) -> str:
|
|
78
|
+
"""
|
|
79
|
+
Convenience function to publish a file to Telegraph.
|
|
80
|
+
|
|
81
|
+
Args:
|
|
82
|
+
file_path: Path to file (.md, .txt, .jpg, .png, .zip, etc.)
|
|
83
|
+
title: Optional title (defaults to filename)
|
|
84
|
+
token: Optional Telegraph token (uses cached token if not provided)
|
|
85
|
+
|
|
86
|
+
Returns:
|
|
87
|
+
str: URL of the published Telegraph page
|
|
88
|
+
|
|
89
|
+
Example:
|
|
90
|
+
>>> from telepress import publish
|
|
91
|
+
>>> url = publish("article.md", title="My Article")
|
|
92
|
+
>>> print(url)
|
|
93
|
+
https://telegra.ph/My-Article-12-07
|
|
94
|
+
"""
|
|
95
|
+
return _get_publisher(token).publish(file_path, title=title)
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def publish_text(content: str, title: str, token: str = None) -> str:
|
|
99
|
+
"""
|
|
100
|
+
Convenience function to publish text content directly to Telegraph.
|
|
101
|
+
|
|
102
|
+
Args:
|
|
103
|
+
content: Markdown or plain text content
|
|
104
|
+
title: Page title (required)
|
|
105
|
+
token: Optional Telegraph token
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
str: URL of the published Telegraph page
|
|
109
|
+
|
|
110
|
+
Example:
|
|
111
|
+
>>> from telepress import publish_text
|
|
112
|
+
>>> url = publish_text("# Hello\n\nThis is my article.", title="Hello World")
|
|
113
|
+
>>> print(url)
|
|
114
|
+
https://telegra.ph/Hello-World-12-07
|
|
115
|
+
"""
|
|
116
|
+
return _get_publisher(token).publish_text(content, title=title)
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from typing import Optional
|
|
3
|
+
from .exceptions import DependencyError, AuthenticationError
|
|
4
|
+
|
|
5
|
+
try:
|
|
6
|
+
from telegraph import Telegraph
|
|
7
|
+
except ImportError:
|
|
8
|
+
Telegraph = None
|
|
9
|
+
|
|
10
|
+
DEFAULT_TOKEN_FILE = os.path.expanduser("~/.telegraph_token")
|
|
11
|
+
|
|
12
|
+
class TelegraphAuth:
|
|
13
|
+
def __init__(self, token_file: str = DEFAULT_TOKEN_FILE):
|
|
14
|
+
if Telegraph is None:
|
|
15
|
+
raise DependencyError("telegraph library is required")
|
|
16
|
+
self.token_file = token_file
|
|
17
|
+
|
|
18
|
+
def get_client(self, token: Optional[str] = None, short_name: str = "TelegraphClient") -> Telegraph:
|
|
19
|
+
"""
|
|
20
|
+
Returns an authenticated Telegraph client.
|
|
21
|
+
Priorities:
|
|
22
|
+
1. Explicit token argument
|
|
23
|
+
2. Stored token in file
|
|
24
|
+
3. Create new account and store token
|
|
25
|
+
"""
|
|
26
|
+
# 1. Explicit token
|
|
27
|
+
if token:
|
|
28
|
+
return Telegraph(access_token=token)
|
|
29
|
+
|
|
30
|
+
# 2. Stored token
|
|
31
|
+
if os.path.exists(self.token_file):
|
|
32
|
+
try:
|
|
33
|
+
with open(self.token_file, 'r') as f:
|
|
34
|
+
stored_token = f.read().strip()
|
|
35
|
+
client = Telegraph(access_token=stored_token)
|
|
36
|
+
# Verify token
|
|
37
|
+
client.get_account_info(['short_name'])
|
|
38
|
+
return client
|
|
39
|
+
except Exception:
|
|
40
|
+
# Log or just proceed to create new
|
|
41
|
+
pass
|
|
42
|
+
|
|
43
|
+
# 3. Create new
|
|
44
|
+
try:
|
|
45
|
+
client = Telegraph()
|
|
46
|
+
response = client.create_account(short_name=short_name)
|
|
47
|
+
new_token = response['access_token']
|
|
48
|
+
|
|
49
|
+
# Ensure directory exists
|
|
50
|
+
os.makedirs(os.path.dirname(self.token_file), exist_ok=True)
|
|
51
|
+
|
|
52
|
+
with open(self.token_file, 'w') as f:
|
|
53
|
+
f.write(new_token)
|
|
54
|
+
|
|
55
|
+
return Telegraph(access_token=new_token)
|
|
56
|
+
except Exception as e:
|
|
57
|
+
raise AuthenticationError(f"Failed to create new Telegraph account: {e}")
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import argparse
|
|
2
|
+
import sys
|
|
3
|
+
from .core import TelegraphPublisher
|
|
4
|
+
from .exceptions import TelePressError
|
|
5
|
+
|
|
6
|
+
def main():
|
|
7
|
+
parser = argparse.ArgumentParser(description="TelePress: Publish files (txt, md, images, zip) to Telegraph.")
|
|
8
|
+
parser.add_argument("file", help="Path to the file to convert")
|
|
9
|
+
parser.add_argument("--title", help="Custom title for the page", default=None)
|
|
10
|
+
parser.add_argument("--token", help="Telegraph access token (optional)", default=None)
|
|
11
|
+
|
|
12
|
+
args = parser.parse_args()
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
publisher = TelegraphPublisher(token=args.token)
|
|
16
|
+
url = publisher.publish(args.file, title=args.title)
|
|
17
|
+
print(f"\n✅ Success! Page created: {url}")
|
|
18
|
+
except TelePressError as e:
|
|
19
|
+
print(f"\n❌ Error: {e}")
|
|
20
|
+
sys.exit(1)
|
|
21
|
+
except Exception as e:
|
|
22
|
+
print(f"\n❌ Unexpected Error: {e}")
|
|
23
|
+
sys.exit(1)
|
|
24
|
+
|
|
25
|
+
if __name__ == "__main__":
|
|
26
|
+
main()
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import List, Dict, Union
|
|
3
|
+
from .utils import sanitize_nodes
|
|
4
|
+
from .exceptions import DependencyError
|
|
5
|
+
|
|
6
|
+
try:
|
|
7
|
+
import markdown
|
|
8
|
+
from telegraph.utils import html_to_nodes
|
|
9
|
+
except ImportError:
|
|
10
|
+
markdown = None
|
|
11
|
+
html_to_nodes = None
|
|
12
|
+
|
|
13
|
+
class MarkdownConverter:
|
|
14
|
+
def __init__(self):
|
|
15
|
+
if markdown is None:
|
|
16
|
+
raise DependencyError("markdown library is required")
|
|
17
|
+
|
|
18
|
+
def convert(self, md_content: str) -> List[Dict]:
|
|
19
|
+
"""Converts Markdown content to Telegraph DOM nodes."""
|
|
20
|
+
html_content = markdown.markdown(md_content)
|
|
21
|
+
|
|
22
|
+
# Pre-process HTML string for headers
|
|
23
|
+
# Telegraph doesn't support h1/h2
|
|
24
|
+
html_content = re.sub(r'<h1', '<h3', html_content)
|
|
25
|
+
html_content = re.sub(r'</h1>', '</h3>', html_content)
|
|
26
|
+
html_content = re.sub(r'<h2', '<h4', html_content)
|
|
27
|
+
html_content = re.sub(r'</h2>', '</h4>', html_content)
|
|
28
|
+
html_content = re.sub(r'<h[56]', '<h4', html_content)
|
|
29
|
+
html_content = re.sub(r'</h[56]>', '</h4>', html_content)
|
|
30
|
+
|
|
31
|
+
if html_to_nodes:
|
|
32
|
+
nodes = html_to_nodes(html_content)
|
|
33
|
+
return sanitize_nodes(nodes)
|
|
34
|
+
else:
|
|
35
|
+
# Fallback (though utils should be present if telegraph is installed)
|
|
36
|
+
return [{'tag': 'p', 'children': [md_content]}]
|