Skip to content

Commit 5d65771

Browse files
authored
Develop (#4)
* additional methods * subscribe button * add youtube support * bump patch version
1 parent de731a1 commit 5d65771

3 files changed

Lines changed: 89 additions & 4 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "python-substack"
3-
version = "0.1.1"
3+
version = "0.1.2"
44
description = "A Python wrapper around the Substack API."
55
authors = ["Paolo Mazza <mazzapaolo2019@gmail.com>"]
66
license = "MIT"

substack/api.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,12 @@ def get_drafts(self, filter: str = None, offset: int = None, limit: int = None):
111111
)
112112
return Api._handle_response(response=response)
113113

114+
def delete_draft(self, draft_id):
115+
response = self._session.delete(
116+
f"{self.publication_url}/drafts/{draft_id}"
117+
)
118+
return Api._handle_response(response=response)
119+
114120
def post_draft(self, body) -> dict:
115121
"""
116122
@@ -189,6 +195,15 @@ def publish_draft(
189195
)
190196
return Api._handle_response(response=response)
191197

198+
def get_image(self, image):
199+
response = self._session.post(
200+
f"{self.publication_url}/image",
201+
json={
202+
"image": image
203+
},
204+
)
205+
return Api._handle_response(response=response)
206+
192207
def get_categories(self):
193208
"""
194209
@@ -235,3 +250,13 @@ def get_single_category(self, category_id: int, category_type: str, page: int |
235250
"more": page_output.get("more", False)
236251
}
237252
return output
253+
254+
def delete_all_drafts(self):
255+
response = None
256+
while True:
257+
drafts = self.get_drafts(filter="draft", limit=10, offset=0)
258+
if len(drafts) == 0:
259+
break
260+
for draft in drafts:
261+
response = self.delete_draft(draft.get("id"))
262+
return response

substack/post.py

Lines changed: 63 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,21 @@ def __init__(self, title: str, subtitle: str, user_id: str):
1212
def add(self, item):
1313
self.draft_body["content"] = self.draft_body.get("content", []) + [{"type": item.get("type")}]
1414
content = item.get("content")
15-
if content is not None:
16-
self.text(content)
15+
if item.get("type") == "captionedImage":
16+
self.captioned_image(item)
17+
elif item.get("type") == "youtube2":
18+
self.youtube(item.get("src"))
19+
else:
20+
if content is not None:
21+
self.add_complex_text(content)
1722

1823
if item.get("type") == "heading":
1924
self.attrs(item.get("level", 1))
25+
26+
marks = item.get("marks")
27+
if marks is not None:
28+
self.marks(marks)
29+
2030
return self
2131

2232
def paragraph(self, content=None):
@@ -41,6 +51,22 @@ def attrs(self, level):
4151
self.draft_body["content"][-1]["attrs"] = content_attrs
4252
return self
4353

54+
def captioned_image(self, value):
55+
content = self.draft_body["content"][-1].get("content", [])
56+
content += [{"type": "image2", "attrs": {
57+
"src": value.get("src"),
58+
"fullscreen": False,
59+
"imageSize": value.get("size", "normal"),
60+
"height": 819,
61+
"width": 1456,
62+
"resizeWidth": 728,
63+
64+
"bytes": None, "alt": None, "title": None, "type": None, "href": None, "belowTheFold": False,
65+
"internalRedirect": None
66+
67+
}}]
68+
self.draft_body["content"][-1]["content"] = content
69+
4470
def text(self, value: str):
4571
"""
4672
@@ -57,11 +83,25 @@ def text(self, value: str):
5783
self.draft_body["content"][-1]["content"] = content
5884
return self
5985

86+
def add_complex_text(self, text):
87+
if isinstance(text, str):
88+
self.text(text)
89+
else:
90+
for chunk in text:
91+
if chunk:
92+
self.text(chunk.get("content")).marks(chunk.get("marks"))
93+
6094
def marks(self, marks):
6195
content = self.draft_body["content"][-1].get("content", [])[-1]
6296
content_marks = content.get("marks", [])
6397
for mark in marks:
64-
content_marks.append({"type": mark})
98+
new_mark = {"type": mark.get("type")}
99+
if mark.get("type") == "link":
100+
href = mark.get("href")
101+
new_mark.update({"attrs": {
102+
"href": href
103+
}})
104+
content_marks.append(new_mark)
65105
content["marks"] = content_marks
66106
return self
67107

@@ -72,3 +112,23 @@ def get_draft(self):
72112
out = vars(self)
73113
out["draft_body"] = json.dumps(out["draft_body"])
74114
return out
115+
116+
def subscribe_with_caption(self, value):
117+
content = self.draft_body["content"][-1].get("content", [])
118+
content += [{"type": "subscribeWidget",
119+
"attrs": {"url": "%%checkout_url%%", "text": "Subscribe"},
120+
"content": [
121+
{
122+
"type": "ctaCaption",
123+
"content": [{"type": "text",
124+
"text": f"Thanks for reading {value}! Subscribe for free to receive new posts and support my work."}]
125+
}
126+
]}]
127+
self.draft_body["content"][-1]["content"] = content
128+
return self
129+
130+
def youtube(self, value):
131+
content_attrs = self.draft_body["content"][-1].get("attrs", {})
132+
content_attrs.update({"videoId": value})
133+
self.draft_body["content"][-1]["attrs"] = content_attrs
134+
return self

0 commit comments

Comments
 (0)