upload-post 2.4.0__tar.gz → 2.6.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.
- {upload_post-2.4.0 → upload_post-2.6.0}/PKG-INFO +2 -1
- {upload_post-2.4.0 → upload_post-2.6.0}/README.md +1 -0
- {upload_post-2.4.0 → upload_post-2.6.0}/setup.py +1 -1
- {upload_post-2.4.0 → upload_post-2.6.0}/upload_post/__init__.py +1 -1
- {upload_post-2.4.0 → upload_post-2.6.0}/upload_post/api_client.py +149 -9
- {upload_post-2.4.0 → upload_post-2.6.0}/upload_post.egg-info/PKG-INFO +2 -1
- {upload_post-2.4.0 → upload_post-2.6.0}/setup.cfg +0 -0
- {upload_post-2.4.0 → upload_post-2.6.0}/upload_post/cli.py +0 -0
- {upload_post-2.4.0 → upload_post-2.6.0}/upload_post.egg-info/SOURCES.txt +0 -0
- {upload_post-2.4.0 → upload_post-2.6.0}/upload_post.egg-info/dependency_links.txt +0 -0
- {upload_post-2.4.0 → upload_post-2.6.0}/upload_post.egg-info/requires.txt +0 -0
- {upload_post-2.4.0 → upload_post-2.6.0}/upload_post.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: upload-post
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.6.0
|
|
4
4
|
Summary: Cross-platform social media upload for TikTok, Instagram, YouTube, LinkedIn, Facebook, Pinterest, Threads, Reddit, Bluesky, Discord, Telegram, and X (Twitter)
|
|
5
5
|
Home-page: https://www.upload-post.com/
|
|
6
6
|
Author: Upload-Post
|
|
@@ -300,6 +300,7 @@ boards = client.get_pinterest_boards("my-profile")
|
|
|
300
300
|
- `allowedCountries` / `blockedCountries` - Country restrictions
|
|
301
301
|
- `hasPaidProductPlacement` - Paid placement flag
|
|
302
302
|
- `recordingDate` - Recording date (ISO 8601)
|
|
303
|
+
- `youtube_playlist_id` - Playlist ID (single string, list, or comma-separated) to add the uploaded video to after publishing
|
|
303
304
|
|
|
304
305
|
### LinkedIn
|
|
305
306
|
- `visibility` - PUBLIC, CONNECTIONS, LOGGED_IN, CONTAINER
|
|
@@ -262,6 +262,7 @@ boards = client.get_pinterest_boards("my-profile")
|
|
|
262
262
|
- `allowedCountries` / `blockedCountries` - Country restrictions
|
|
263
263
|
- `hasPaidProductPlacement` - Paid placement flag
|
|
264
264
|
- `recordingDate` - Recording date (ISO 8601)
|
|
265
|
+
- `youtube_playlist_id` - Playlist ID (single string, list, or comma-separated) to add the uploaded video to after publishing
|
|
265
266
|
|
|
266
267
|
### LinkedIn
|
|
267
268
|
- `visibility` - PUBLIC, CONNECTIONS, LOGGED_IN, CONTAINER
|
|
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
|
|
|
5
5
|
|
|
6
6
|
setup(
|
|
7
7
|
name="upload-post",
|
|
8
|
-
version="2.
|
|
8
|
+
version="2.6.0",
|
|
9
9
|
author="Upload-Post",
|
|
10
10
|
author_email="hi@img2html.com",
|
|
11
11
|
description="Cross-platform social media upload for TikTok, Instagram, YouTube, LinkedIn, Facebook, Pinterest, Threads, Reddit, Bluesky, Discord, Telegram, and X (Twitter)",
|
|
@@ -262,6 +262,12 @@ class UploadPostClient:
|
|
|
262
262
|
data.append(("hasPaidProductPlacement", str(kwargs["hasPaidProductPlacement"]).lower()))
|
|
263
263
|
if kwargs.get("recordingDate"):
|
|
264
264
|
data.append(("recordingDate", kwargs["recordingDate"]))
|
|
265
|
+
playlist_value = kwargs.get("youtube_playlist_id")
|
|
266
|
+
if playlist_value:
|
|
267
|
+
if isinstance(playlist_value, (list, tuple)):
|
|
268
|
+
playlist_value = ",".join(str(p).strip() for p in playlist_value if str(p).strip())
|
|
269
|
+
if playlist_value:
|
|
270
|
+
data.append(("youtube_playlist_id", str(playlist_value)))
|
|
265
271
|
if kwargs.get("subtitles"):
|
|
266
272
|
for idx, sub in enumerate(kwargs["subtitles"]):
|
|
267
273
|
if sub.get("language"):
|
|
@@ -464,6 +470,8 @@ class UploadPostClient:
|
|
|
464
470
|
blockedCountries: Comma-separated country codes
|
|
465
471
|
hasPaidProductPlacement: Paid placement flag
|
|
466
472
|
recordingDate: Recording date (ISO 8601)
|
|
473
|
+
youtube_playlist_id: Playlist ID (or list/comma-separated of IDs) to add
|
|
474
|
+
the uploaded video to after publishing
|
|
467
475
|
subtitles: List of subtitle dicts with keys: language (BCP-47),
|
|
468
476
|
name (display name), file (path to SRT/VTT file), url (subtitle URL)
|
|
469
477
|
|
|
@@ -904,6 +912,53 @@ class UploadPostClient:
|
|
|
904
912
|
"""
|
|
905
913
|
return self._request("/uploadposts/history", "GET", params={"page": page, "limit": limit})
|
|
906
914
|
|
|
915
|
+
def retry_post(
|
|
916
|
+
self,
|
|
917
|
+
request_id: Optional[str] = None,
|
|
918
|
+
job_id: Optional[str] = None
|
|
919
|
+
) -> Dict:
|
|
920
|
+
"""
|
|
921
|
+
Retry a failed post.
|
|
922
|
+
|
|
923
|
+
Args:
|
|
924
|
+
request_id: Request ID of the post to retry.
|
|
925
|
+
job_id: Job ID of the post to retry.
|
|
926
|
+
|
|
927
|
+
One of request_id or job_id is required.
|
|
928
|
+
|
|
929
|
+
Returns:
|
|
930
|
+
Retry result.
|
|
931
|
+
"""
|
|
932
|
+
json_data = {}
|
|
933
|
+
if request_id is not None:
|
|
934
|
+
json_data["request_id"] = request_id
|
|
935
|
+
if job_id is not None:
|
|
936
|
+
json_data["job_id"] = job_id
|
|
937
|
+
return self._request("/uploadposts/posts/retry", "POST", json_data=json_data)
|
|
938
|
+
|
|
939
|
+
def unpublish_post(
|
|
940
|
+
self,
|
|
941
|
+
user: str,
|
|
942
|
+
platform: str,
|
|
943
|
+
post_id: str
|
|
944
|
+
) -> Dict:
|
|
945
|
+
"""
|
|
946
|
+
Unpublish (delete) a previously published post.
|
|
947
|
+
|
|
948
|
+
Args:
|
|
949
|
+
user: Profile username.
|
|
950
|
+
platform: Platform name (facebook, youtube, x, linkedin, threads).
|
|
951
|
+
post_id: ID of the published post to unpublish.
|
|
952
|
+
|
|
953
|
+
Returns:
|
|
954
|
+
Unpublish result.
|
|
955
|
+
"""
|
|
956
|
+
return self._request("/uploadposts/posts/unpublish", "POST", json_data={
|
|
957
|
+
"user": user,
|
|
958
|
+
"platform": platform,
|
|
959
|
+
"post_id": post_id
|
|
960
|
+
})
|
|
961
|
+
|
|
907
962
|
def get_analytics(self, profile_username: str, platforms: Optional[List[str]] = None,
|
|
908
963
|
page_id: Optional[str] = None, page_urn: Optional[str] = None) -> Dict:
|
|
909
964
|
"""
|
|
@@ -913,7 +968,10 @@ class UploadPostClient:
|
|
|
913
968
|
profile_username: Profile username.
|
|
914
969
|
platforms: Filter by platforms (instagram, linkedin, facebook, x, youtube, tiktok, threads, pinterest, reddit).
|
|
915
970
|
page_id: Facebook Page ID (required for Facebook analytics).
|
|
916
|
-
page_urn: LinkedIn page URN
|
|
971
|
+
page_urn: LinkedIn organization/company page URN or numeric ID. LinkedIn
|
|
972
|
+
analytics are only available for pages you administer; personal profiles
|
|
973
|
+
are not supported (LinkedIn's API exposes no member-level analytics). If
|
|
974
|
+
omitted, the first administered organization page is used.
|
|
917
975
|
|
|
918
976
|
Returns:
|
|
919
977
|
Analytics data per platform. For Instagram, the response includes both
|
|
@@ -1291,32 +1349,43 @@ class UploadPostClient:
|
|
|
1291
1349
|
def get_post_comments(
|
|
1292
1350
|
self,
|
|
1293
1351
|
user: str,
|
|
1352
|
+
platform: str = "instagram",
|
|
1294
1353
|
post_id: Optional[str] = None,
|
|
1295
|
-
post_url: Optional[str] = None
|
|
1354
|
+
post_url: Optional[str] = None,
|
|
1355
|
+
limit: Optional[int] = None,
|
|
1356
|
+
after: Optional[str] = None
|
|
1296
1357
|
) -> Dict:
|
|
1297
1358
|
"""
|
|
1298
|
-
Get comments on
|
|
1359
|
+
Get comments on a post.
|
|
1299
1360
|
|
|
1300
1361
|
Args:
|
|
1301
1362
|
user: Profile username.
|
|
1302
|
-
|
|
1303
|
-
|
|
1363
|
+
platform: Platform name (instagram, facebook, youtube, linkedin).
|
|
1364
|
+
post_id: Post/media ID (provide post_id or post_url).
|
|
1365
|
+
post_url: Full post URL (provide post_id or post_url).
|
|
1366
|
+
limit: Maximum number of comments to return.
|
|
1367
|
+
after: Pagination cursor for the next page of comments.
|
|
1304
1368
|
|
|
1305
1369
|
Returns:
|
|
1306
1370
|
Comments data including comment IDs, text, timestamps, and user info.
|
|
1307
1371
|
"""
|
|
1308
|
-
params = {"platform":
|
|
1372
|
+
params = {"platform": platform, "user": user}
|
|
1309
1373
|
if post_id:
|
|
1310
1374
|
params["post_id"] = post_id
|
|
1311
1375
|
if post_url:
|
|
1312
1376
|
params["post_url"] = post_url
|
|
1377
|
+
if limit is not None:
|
|
1378
|
+
params["limit"] = limit
|
|
1379
|
+
if after is not None:
|
|
1380
|
+
params["after"] = after
|
|
1313
1381
|
return self._request("/uploadposts/comments", "GET", params=params)
|
|
1314
1382
|
|
|
1315
1383
|
def reply_to_comment(
|
|
1316
1384
|
self,
|
|
1317
1385
|
user: str,
|
|
1318
1386
|
comment_id: str,
|
|
1319
|
-
message: str
|
|
1387
|
+
message: str,
|
|
1388
|
+
buttons: Optional[List[Dict]] = None
|
|
1320
1389
|
) -> Dict:
|
|
1321
1390
|
"""
|
|
1322
1391
|
Send a private reply (DM) to the author of an Instagram comment.
|
|
@@ -1325,16 +1394,21 @@ class UploadPostClient:
|
|
|
1325
1394
|
user: Profile username.
|
|
1326
1395
|
comment_id: Comment ID from get_post_comments.
|
|
1327
1396
|
message: Reply message text.
|
|
1397
|
+
buttons: Optional list of web_url buttons (max 3) rendered in the Instagram
|
|
1398
|
+
DM. Each item is a dict like {"title": "Open", "url": "https://..."}.
|
|
1328
1399
|
|
|
1329
1400
|
Returns:
|
|
1330
1401
|
Reply result with recipient_id and message_id.
|
|
1331
1402
|
"""
|
|
1332
|
-
|
|
1403
|
+
json_data = {
|
|
1333
1404
|
"platform": "instagram",
|
|
1334
1405
|
"user": user,
|
|
1335
1406
|
"comment_id": comment_id,
|
|
1336
1407
|
"message": message
|
|
1337
|
-
}
|
|
1408
|
+
}
|
|
1409
|
+
if buttons is not None:
|
|
1410
|
+
json_data["buttons"] = buttons
|
|
1411
|
+
return self._request("/uploadposts/comments/reply", "POST", json_data=json_data)
|
|
1338
1412
|
|
|
1339
1413
|
def public_reply_to_comment(
|
|
1340
1414
|
self,
|
|
@@ -1360,6 +1434,72 @@ class UploadPostClient:
|
|
|
1360
1434
|
"message": message
|
|
1361
1435
|
})
|
|
1362
1436
|
|
|
1437
|
+
def create_comment(
|
|
1438
|
+
self,
|
|
1439
|
+
user: str,
|
|
1440
|
+
platform: str,
|
|
1441
|
+
message: str,
|
|
1442
|
+
post_id: Optional[str] = None,
|
|
1443
|
+
post_url: Optional[str] = None,
|
|
1444
|
+
comment_id: Optional[str] = None
|
|
1445
|
+
) -> Dict:
|
|
1446
|
+
"""
|
|
1447
|
+
Create a comment on a post, or reply to an existing comment.
|
|
1448
|
+
|
|
1449
|
+
Args:
|
|
1450
|
+
user: Profile username.
|
|
1451
|
+
platform: Platform name (instagram, facebook, youtube, linkedin).
|
|
1452
|
+
message: Comment text.
|
|
1453
|
+
post_id: Post/media ID to comment on.
|
|
1454
|
+
post_url: Full post URL to comment on.
|
|
1455
|
+
comment_id: Existing comment ID to reply to.
|
|
1456
|
+
|
|
1457
|
+
One of post_id, post_url or comment_id is required.
|
|
1458
|
+
|
|
1459
|
+
Returns:
|
|
1460
|
+
Creation result with the new comment ID.
|
|
1461
|
+
"""
|
|
1462
|
+
json_data = {
|
|
1463
|
+
"platform": platform,
|
|
1464
|
+
"user": user,
|
|
1465
|
+
"message": message
|
|
1466
|
+
}
|
|
1467
|
+
if post_id is not None:
|
|
1468
|
+
json_data["post_id"] = post_id
|
|
1469
|
+
if post_url is not None:
|
|
1470
|
+
json_data["post_url"] = post_url
|
|
1471
|
+
if comment_id is not None:
|
|
1472
|
+
json_data["comment_id"] = comment_id
|
|
1473
|
+
return self._request("/uploadposts/comments/create", "POST", json_data=json_data)
|
|
1474
|
+
|
|
1475
|
+
def delete_comment(
|
|
1476
|
+
self,
|
|
1477
|
+
user: str,
|
|
1478
|
+
platform: str,
|
|
1479
|
+
comment_id: str,
|
|
1480
|
+
post_id: Optional[str] = None
|
|
1481
|
+
) -> Dict:
|
|
1482
|
+
"""
|
|
1483
|
+
Delete a comment on a post.
|
|
1484
|
+
|
|
1485
|
+
Args:
|
|
1486
|
+
user: Profile username.
|
|
1487
|
+
platform: Platform name (instagram, facebook, youtube, linkedin).
|
|
1488
|
+
comment_id: Comment ID to delete.
|
|
1489
|
+
post_id: Post URN (required for LinkedIn).
|
|
1490
|
+
|
|
1491
|
+
Returns:
|
|
1492
|
+
Deletion result.
|
|
1493
|
+
"""
|
|
1494
|
+
json_data = {
|
|
1495
|
+
"platform": platform,
|
|
1496
|
+
"user": user,
|
|
1497
|
+
"comment_id": comment_id
|
|
1498
|
+
}
|
|
1499
|
+
if post_id is not None:
|
|
1500
|
+
json_data["post_id"] = post_id
|
|
1501
|
+
return self._request("/uploadposts/comments/delete", "DELETE", json_data=json_data)
|
|
1502
|
+
|
|
1363
1503
|
# ==================== Google Business ====================
|
|
1364
1504
|
|
|
1365
1505
|
def get_google_business_locations(self, profile: Optional[str] = None) -> Dict:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: upload-post
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.6.0
|
|
4
4
|
Summary: Cross-platform social media upload for TikTok, Instagram, YouTube, LinkedIn, Facebook, Pinterest, Threads, Reddit, Bluesky, Discord, Telegram, and X (Twitter)
|
|
5
5
|
Home-page: https://www.upload-post.com/
|
|
6
6
|
Author: Upload-Post
|
|
@@ -300,6 +300,7 @@ boards = client.get_pinterest_boards("my-profile")
|
|
|
300
300
|
- `allowedCountries` / `blockedCountries` - Country restrictions
|
|
301
301
|
- `hasPaidProductPlacement` - Paid placement flag
|
|
302
302
|
- `recordingDate` - Recording date (ISO 8601)
|
|
303
|
+
- `youtube_playlist_id` - Playlist ID (single string, list, or comma-separated) to add the uploaded video to after publishing
|
|
303
304
|
|
|
304
305
|
### LinkedIn
|
|
305
306
|
- `visibility` - PUBLIC, CONNECTIONS, LOGGED_IN, CONTAINER
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|