tumblrbot 1.1.2__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.2 → tumblrbot-1.1.3}/PKG-INFO +2 -2
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/README.md +1 -1
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/pyproject.toml +1 -1
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/src/tumblrbot/flow/download.py +17 -7
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/src/tumblrbot/utils/models.py +7 -4
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/src/tumblrbot/utils/tumblr.py +3 -11
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/.github/dependabot.yml +0 -0
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/.gitignore +0 -0
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/UNLICENSE +0 -0
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/src/tumblrbot/__init__.py +0 -0
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/src/tumblrbot/__main__.py +0 -0
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/src/tumblrbot/flow/__init__.py +0 -0
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/src/tumblrbot/flow/examples.py +0 -0
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/src/tumblrbot/flow/fine_tune.py +0 -0
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/src/tumblrbot/flow/generate.py +0 -0
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/src/tumblrbot/utils/__init__.py +0 -0
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/src/tumblrbot/utils/common.py +0 -0
- {tumblrbot-1.1.2 → tumblrbot-1.1.3}/src/tumblrbot/utils/settings.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tumblrbot
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.3
|
|
4
4
|
Summary: An updated bot that posts to Tumblr, based on your very own blog!
|
|
5
5
|
Requires-Python: >= 3.13
|
|
6
6
|
Description-Content-Type: text/markdown
|
|
@@ -82,8 +82,8 @@ This fork is largely a rewrite of the source code with similarities in its struc
|
|
|
82
82
|
To-Do:
|
|
83
83
|
- Add documentation.
|
|
84
84
|
- Finish updating [README.md].
|
|
85
|
-
- Look into places more-itertools can help.
|
|
86
85
|
- Change the differences list to instead just be a list of features.
|
|
86
|
+
- Allow adding arbitrary data to examples.
|
|
87
87
|
|
|
88
88
|
|
|
89
89
|
**Please submit an issue or contact us for features you want to added/reimplemented.**
|
|
@@ -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
|
},
|
|
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
|