tumblrbot 1.1.1__tar.gz → 1.1.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.
- tumblrbot-1.1.3/PKG-INFO +108 -0
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/README.md +1 -1
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/pyproject.toml +2 -1
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/src/tumblrbot/flow/download.py +17 -7
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/src/tumblrbot/utils/models.py +7 -4
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/src/tumblrbot/utils/tumblr.py +3 -11
- tumblrbot-1.1.1/PKG-INFO +0 -15
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/.github/dependabot.yml +0 -0
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/.gitignore +0 -0
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/UNLICENSE +0 -0
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/src/tumblrbot/__init__.py +0 -0
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/src/tumblrbot/__main__.py +0 -0
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/src/tumblrbot/flow/__init__.py +0 -0
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/src/tumblrbot/flow/examples.py +0 -0
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/src/tumblrbot/flow/fine_tune.py +0 -0
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/src/tumblrbot/flow/generate.py +0 -0
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/src/tumblrbot/utils/__init__.py +0 -0
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/src/tumblrbot/utils/common.py +0 -0
- {tumblrbot-1.1.1 → tumblrbot-1.1.3}/src/tumblrbot/utils/settings.py +0 -0
tumblrbot-1.1.3/PKG-INFO
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tumblrbot
|
|
3
|
+
Version: 1.1.3
|
|
4
|
+
Summary: An updated bot that posts to Tumblr, based on your very own blog!
|
|
5
|
+
Requires-Python: >= 3.13
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: more-itertools
|
|
8
|
+
Requires-Dist: openai
|
|
9
|
+
Requires-Dist: pydantic
|
|
10
|
+
Requires-Dist: pydantic-settings
|
|
11
|
+
Requires-Dist: requests
|
|
12
|
+
Requires-Dist: requests-oauthlib
|
|
13
|
+
Requires-Dist: rich
|
|
14
|
+
Requires-Dist: tiktoken
|
|
15
|
+
Requires-Dist: tomlkit
|
|
16
|
+
Project-URL: Source, https://github.com/MaidThatPrograms/tumblrbot
|
|
17
|
+
|
|
18
|
+
[OpenAI]: https://pypi.org/project/openai
|
|
19
|
+
[Python]: https://python.org/download
|
|
20
|
+
[Rich]: https://pypi.org/project/rich
|
|
21
|
+
|
|
22
|
+
[gpt-4.1-nano-2025-04-14]: https://platform.openai.com/docs/models/gpt-4.1-nano
|
|
23
|
+
[Moderation API]: https://platform.openai.com/docs/api-reference/moderations
|
|
24
|
+
[New Post Format]: https://tumblr.com/docs/npf
|
|
25
|
+
[OAuth 2.0]: https://www.tumblr.com/docs/en/api/v2#oauth2-authorization
|
|
26
|
+
[pip]: https://pypi.org
|
|
27
|
+
|
|
28
|
+
[Download]: tumblrbot/flow/download.py
|
|
29
|
+
[Examples]: tumblrbot/flow/examples.py
|
|
30
|
+
[Fine-Tune]: tumblrbot/flow/fine_tune.py
|
|
31
|
+
[Generate]: tumblrbot/flow/generate.py
|
|
32
|
+
[Settings]: tumblrbot/utils/settings.py
|
|
33
|
+
[Main]: __main__.py
|
|
34
|
+
[README.md]: README.md
|
|
35
|
+
|
|
36
|
+
# tumblrbot
|
|
37
|
+
[](https://python.org/pypi/tumblrbot)
|
|
38
|
+
|
|
39
|
+
Description of original project:
|
|
40
|
+
> 4tv-tumblrbot was a collaborative project I embarked on with my close friend Dima, who goes by @smoqueen on Tumblr. The aim of this endeavor was straightforward yet silly: to develop a Tumblr bot powered by a machine-learning model. This bot would be specifically trained on the content from a particular Tumblr blog or a selected set of blogs, allowing it to mimic the style, tone, and thematic essence of the original posts.
|
|
41
|
+
|
|
42
|
+
This fork is largely a rewrite of the source code with similarities in its structure and process:
|
|
43
|
+
- Updates:
|
|
44
|
+
- Updated to [OAuth 2.0].
|
|
45
|
+
- Updated to the [New Post Format].
|
|
46
|
+
- Updated to the latest version of [OpenAI].
|
|
47
|
+
- Updated the [base model version][Settings] to [gpt-4.1-nano-2025-04-14].
|
|
48
|
+
- Removed features:
|
|
49
|
+
- [Generation][Generate]:
|
|
50
|
+
- Removed clearing drafts behavior.
|
|
51
|
+
- [Training][Examples]:
|
|
52
|
+
- Removed exports that had HTML or reblogs.
|
|
53
|
+
- Removed special word-replacement behavior.
|
|
54
|
+
- Removed filtering by year.
|
|
55
|
+
- Removed setup and related files.
|
|
56
|
+
- Changed/Added features:
|
|
57
|
+
- [Generation][Generate]:
|
|
58
|
+
- Added a link to the blog's draft page.
|
|
59
|
+
- Added error checking for uploading drafts.
|
|
60
|
+
- [Training][Examples]:
|
|
61
|
+
- Added the option to [Download] the latest posts from the [specified blogs][Settings].
|
|
62
|
+
- Added the option to remove posts flagged by the [Moderation API].
|
|
63
|
+
- Added the option to automatically [Fine-Tune] the examples on the [specified base model][Settings].
|
|
64
|
+
- Changed to now escape examples automatically.
|
|
65
|
+
- Set encoding for reading post data to `UTF-8` to fix decoding errors.
|
|
66
|
+
- Added newlines between paragraphs.
|
|
67
|
+
- Removed "ALT", submission, ask, and poll text from posts.
|
|
68
|
+
- Improved the estimated token counts and costs.
|
|
69
|
+
- Changed to [Rich] for output.
|
|
70
|
+
- Added progress bars.
|
|
71
|
+
- Added post previews.
|
|
72
|
+
- Added color, formatting, and more information to output.
|
|
73
|
+
- Created a [guided utility][Main] for every step of building your bot blog.
|
|
74
|
+
- Maid scripts wait for user input before the console closes.
|
|
75
|
+
- Added comand-line options to override [Settings] options.
|
|
76
|
+
- Added behavior to regenerate the default [config.toml][Settings] and [env.toml][Settings] if missing.
|
|
77
|
+
- Renamed several files.
|
|
78
|
+
- Renamed several [Settings] options.
|
|
79
|
+
- Changed the value of several [Settings] options.
|
|
80
|
+
- Added full type-checking coverage (fully importable from third-party scripts).
|
|
81
|
+
|
|
82
|
+
To-Do:
|
|
83
|
+
- Add documentation.
|
|
84
|
+
- Finish updating [README.md].
|
|
85
|
+
- Change the differences list to instead just be a list of features.
|
|
86
|
+
- Allow adding arbitrary data to examples.
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
**Please submit an issue or contact us for features you want to added/reimplemented.**
|
|
90
|
+
|
|
91
|
+
## Installation
|
|
92
|
+
1. Install the latest version of [Python]:
|
|
93
|
+
- Windows: `winget install python3`
|
|
94
|
+
- Linux (apt): `apt install python-pip`
|
|
95
|
+
- Linux (pacman): `pacman install python-pip`
|
|
96
|
+
1. Install the [pip] package: `pip install tumblrbot`
|
|
97
|
+
- Alternatively, you can install from this repository: `pip install git+https://github.com/MaidThatPrograms/tumblrbot.git`
|
|
98
|
+
- On Linux, you will have to make a virtual environment.
|
|
99
|
+
|
|
100
|
+
## Usage
|
|
101
|
+
Run `tumblrbot` from anywhere. Run `tumblrbot --help` for command-line options.
|
|
102
|
+
|
|
103
|
+
## Obtaining Tokens
|
|
104
|
+
> WIP
|
|
105
|
+
|
|
106
|
+
## Configuration
|
|
107
|
+
> WIP
|
|
108
|
+
|
|
@@ -65,8 +65,8 @@ This fork is largely a rewrite of the source code with similarities in its struc
|
|
|
65
65
|
To-Do:
|
|
66
66
|
- Add documentation.
|
|
67
67
|
- Finish updating [README.md].
|
|
68
|
-
- Look into places more-itertools can help.
|
|
69
68
|
- Change the differences list to instead just be a list of features.
|
|
69
|
+
- Allow adding arbitrary data to examples.
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
**Please submit an issue or contact us for features you want to added/reimplemented.**
|
|
@@ -7,12 +7,12 @@ from tumblrbot.utils.models import Post
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class PostDownloader(UtilClass):
|
|
10
|
-
def paginate_posts(self, blog_identifier: str,
|
|
11
|
-
task_id = live.progress.add_task(f"Downloading posts from '{blog_identifier}'...", total=None, completed=
|
|
10
|
+
def paginate_posts(self, blog_identifier: str, completed: int, after: int, fp: TextIOBase, live: PreviewLive) -> None:
|
|
11
|
+
task_id = live.progress.add_task(f"Downloading posts from '{blog_identifier}'...", total=None, completed=completed)
|
|
12
12
|
|
|
13
13
|
while True:
|
|
14
|
-
response = self.tumblr.retrieve_published_posts(blog_identifier,
|
|
15
|
-
live.progress.update(task_id, total=response["blog"]["posts"], completed=
|
|
14
|
+
response = self.tumblr.retrieve_published_posts(blog_identifier, after=after).json()["response"]
|
|
15
|
+
live.progress.update(task_id, total=response["blog"]["posts"], completed=completed)
|
|
16
16
|
|
|
17
17
|
if posts := response["posts"]:
|
|
18
18
|
for post in posts:
|
|
@@ -20,11 +20,12 @@ class PostDownloader(UtilClass):
|
|
|
20
20
|
fp.write("\n")
|
|
21
21
|
|
|
22
22
|
model = Post.model_validate(post)
|
|
23
|
+
after = model.timestamp
|
|
23
24
|
live.custom_update(model)
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
completed += len(posts)
|
|
26
27
|
else:
|
|
27
|
-
|
|
28
|
+
return
|
|
28
29
|
|
|
29
30
|
def get_data_path(self, blog_identifier: str) -> Path:
|
|
30
31
|
return (self.config.data_directory / blog_identifier).with_suffix(".jsonl")
|
|
@@ -39,10 +40,19 @@ class PostDownloader(UtilClass):
|
|
|
39
40
|
for blog_identifier in self.config.download_blog_identifiers:
|
|
40
41
|
data_path = self.get_data_path(blog_identifier)
|
|
41
42
|
|
|
43
|
+
completed = 0
|
|
44
|
+
after = 0
|
|
45
|
+
if data_path.exists():
|
|
46
|
+
lines = data_path.read_text("utf_8").splitlines() if data_path.exists() else []
|
|
47
|
+
completed = len(lines)
|
|
48
|
+
if lines:
|
|
49
|
+
after = Post.model_validate_json(lines[-1]).timestamp
|
|
50
|
+
|
|
42
51
|
with data_path.open("a", encoding="utf_8") as fp:
|
|
43
52
|
self.paginate_posts(
|
|
44
53
|
blog_identifier,
|
|
45
|
-
|
|
54
|
+
completed,
|
|
55
|
+
after,
|
|
46
56
|
fp,
|
|
47
57
|
live,
|
|
48
58
|
)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import Any, Literal, override
|
|
2
2
|
|
|
3
3
|
from openai import BaseModel
|
|
4
|
-
from pydantic import ConfigDict
|
|
4
|
+
from pydantic import ConfigDict
|
|
5
5
|
from pydantic.json_schema import SkipJsonSchema
|
|
6
6
|
from rich.panel import Panel
|
|
7
7
|
|
|
@@ -22,11 +22,14 @@ class Post(FullyValidatedModel):
|
|
|
22
22
|
text: str = ""
|
|
23
23
|
blocks: list[int] = [] # noqa: RUF012
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
timestamp: SkipJsonSchema[int] = 0
|
|
26
|
+
tags: list[str] = [] # noqa: RUF012
|
|
27
|
+
state: SkipJsonSchema[Literal["published", "queued", "draft", "private", "unapproved"]] = "published"
|
|
28
|
+
|
|
26
29
|
content: SkipJsonSchema[list[Block]] = [] # noqa: RUF012
|
|
27
30
|
layout: SkipJsonSchema[list[Block]] = [] # noqa: RUF012
|
|
28
31
|
trail: SkipJsonSchema[list[Any]] = [] # noqa: RUF012
|
|
29
|
-
|
|
32
|
+
|
|
30
33
|
is_submission: SkipJsonSchema[bool] = False
|
|
31
34
|
|
|
32
35
|
def __rich__(self) -> Panel:
|
|
@@ -39,7 +39,6 @@ class TumblrClient(OAuth2Session):
|
|
|
39
39
|
|
|
40
40
|
rich.print(f"Please go to {authorization_url} and authorize access.")
|
|
41
41
|
authorization_response = Prompt.ask("Enter the full callback URL")
|
|
42
|
-
rich.print("\n")
|
|
43
42
|
|
|
44
43
|
self.token_saver(
|
|
45
44
|
self.fetch_token( # pyright: ignore[reportUnknownMemberType]
|
|
@@ -58,21 +57,14 @@ class TumblrClient(OAuth2Session):
|
|
|
58
57
|
try:
|
|
59
58
|
response.raise_for_status()
|
|
60
59
|
except HTTPError as error:
|
|
61
|
-
|
|
62
|
-
if error_description := json.get("error_description", None):
|
|
63
|
-
error.add_note(error_description)
|
|
64
|
-
elif errors := json.get("errors", None):
|
|
65
|
-
for suberror in errors:
|
|
66
|
-
error.add_note(f"{suberror['title']} ({suberror['code']}): {suberror['detail']}")
|
|
67
|
-
else:
|
|
68
|
-
error.add_note(str(json))
|
|
60
|
+
error.add_note(response.text)
|
|
69
61
|
raise
|
|
70
62
|
|
|
71
|
-
def retrieve_published_posts(self, blog_identifier: str,
|
|
63
|
+
def retrieve_published_posts(self, blog_identifier: str, after: int) -> Response:
|
|
72
64
|
return self.get(
|
|
73
65
|
f"https://api.tumblr.com/v2/blog/{blog_identifier}/posts",
|
|
74
66
|
params={
|
|
75
|
-
"
|
|
67
|
+
"after": after,
|
|
76
68
|
"sort": "asc",
|
|
77
69
|
"npf": True,
|
|
78
70
|
},
|
tumblrbot-1.1.1/PKG-INFO
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: tumblrbot
|
|
3
|
-
Version: 1.1.1
|
|
4
|
-
Summary: An updated bot that posts to Tumblr, based on your very own blog!
|
|
5
|
-
Requires-Python: >= 3.13
|
|
6
|
-
Requires-Dist: more-itertools
|
|
7
|
-
Requires-Dist: openai
|
|
8
|
-
Requires-Dist: pydantic
|
|
9
|
-
Requires-Dist: pydantic-settings
|
|
10
|
-
Requires-Dist: requests
|
|
11
|
-
Requires-Dist: requests-oauthlib
|
|
12
|
-
Requires-Dist: rich
|
|
13
|
-
Requires-Dist: tiktoken
|
|
14
|
-
Requires-Dist: tomlkit
|
|
15
|
-
Project-URL: Source, https://github.com/MaidThatPrograms/tumblrbot
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|