tiktokautouploader 2.95__py2.py3-none-any.whl → 3.2__py2.py3-none-any.whl
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.
- tiktokautouploader/function.py +262 -144
- {tiktokautouploader-2.95.dist-info → tiktokautouploader-3.2.dist-info}/METADATA +26 -12
- tiktokautouploader-3.2.dist-info/RECORD +7 -0
- tiktokautouploader-2.95.dist-info/RECORD +0 -7
- {tiktokautouploader-2.95.dist-info → tiktokautouploader-3.2.dist-info}/WHEEL +0 -0
- {tiktokautouploader-2.95.dist-info → tiktokautouploader-3.2.dist-info}/licenses/LICENSE.md +0 -0
tiktokautouploader/function.py
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
from playwright.sync_api import sync_playwright
|
2
2
|
import json
|
3
3
|
import time
|
4
|
-
import inference
|
5
4
|
import subprocess
|
5
|
+
from inference_sdk import InferenceHTTPClient
|
6
6
|
import pkg_resources
|
7
7
|
import requests
|
8
8
|
from PIL import Image
|
@@ -11,15 +11,26 @@ import os
|
|
11
11
|
import warnings
|
12
12
|
warnings.simplefilter("ignore")
|
13
13
|
|
14
|
-
|
15
|
-
|
14
|
+
|
15
|
+
def check_for_updates():
|
16
|
+
current_version = pkg_resources.get_distribution("tiktokautouploader").version
|
17
|
+
response = requests.get("https://pypi.org/pypi/tiktokautouploader/json")
|
18
|
+
|
19
|
+
if response.status_code == 200:
|
20
|
+
latest_version = response.json()["info"]["version"]
|
21
|
+
if current_version != latest_version:
|
22
|
+
print(f"WARNING: You are using version {current_version} of tiktokautouploader, "
|
23
|
+
f"PLEASE UPDATE TO LATEST VERSION {latest_version} FOR BEST EXPERIENCE.")
|
24
|
+
|
25
|
+
def login_warning(accountname):
|
26
|
+
print(f"NO COOKIES FILE FOUND FOR ACCOUNT {accountname}, PLEASE LOG-IN TO {accountname} WHEN PROMPTED")
|
16
27
|
|
17
28
|
def save_cookies(cookies):
|
18
29
|
with open('TK_cookies.json', 'w') as file:
|
19
30
|
json.dump(cookies, file, indent=4)
|
20
31
|
|
21
|
-
def check_expiry():
|
22
|
-
with open('
|
32
|
+
def check_expiry(accountname):
|
33
|
+
with open(f'TK_cookies_{accountname}.json', 'r') as file:
|
23
34
|
cookies = json.load(file)
|
24
35
|
|
25
36
|
current_time = int(time.time())
|
@@ -128,21 +139,27 @@ def download_image(image_url):
|
|
128
139
|
f.write(response.content)
|
129
140
|
return image_path
|
130
141
|
|
131
|
-
|
132
142
|
def run_inference_on_image_tougher(image_path, object):
|
133
143
|
|
134
|
-
|
135
|
-
|
144
|
+
k = 'n|KIeDZnRZiJ};iVHz;R'
|
145
|
+
rk = ''.join(chr((ord(c) - 3) % 256) for c in k)
|
146
|
+
|
147
|
+
CLIENT = InferenceHTTPClient(
|
148
|
+
api_url="https://detect.roboflow.com",
|
149
|
+
api_key=f"{rk}"
|
150
|
+
)
|
151
|
+
|
152
|
+
results = CLIENT.infer(image_path, model_id="captcha-2-6ehbe/2")
|
136
153
|
|
137
154
|
class_names = []
|
138
155
|
bounding_boxes = []
|
139
|
-
for obj in results[
|
140
|
-
class_names.append(obj
|
156
|
+
for obj in results['predictions']:
|
157
|
+
class_names.append(obj['class'])
|
141
158
|
bounding_boxes.append({
|
142
|
-
"x": obj
|
143
|
-
"y": obj
|
144
|
-
"width": obj
|
145
|
-
"height": obj
|
159
|
+
"x": obj['x'],
|
160
|
+
"y": obj['y'],
|
161
|
+
"width": obj['width'],
|
162
|
+
"height": obj['height']
|
146
163
|
})
|
147
164
|
|
148
165
|
bounding_box = []
|
@@ -157,34 +174,40 @@ def run_inference_on_image_tougher(image_path, object):
|
|
157
174
|
|
158
175
|
def run_inference_on_image(image_path):
|
159
176
|
|
160
|
-
|
161
|
-
|
177
|
+
k = 'n|KIeDZnRZiJ};iVHz;R'
|
178
|
+
rk = ''.join(chr((ord(c) - 3) % 256) for c in k)
|
179
|
+
|
180
|
+
CLIENT = InferenceHTTPClient(
|
181
|
+
api_url="https://detect.roboflow.com",
|
182
|
+
api_key=f"{rk}"
|
183
|
+
)
|
184
|
+
|
185
|
+
results = CLIENT.infer(image_path, model_id="tk-3nwi9/2")
|
162
186
|
|
163
187
|
class_names = []
|
164
188
|
bounding_boxes = []
|
165
|
-
for obj in results[
|
166
|
-
class_names.append(obj
|
189
|
+
for obj in results['predictions']:
|
190
|
+
class_names.append(obj['class'])
|
167
191
|
bounding_boxes.append({
|
168
|
-
"x": obj
|
169
|
-
"y": obj
|
170
|
-
"width": obj
|
171
|
-
"height": obj
|
192
|
+
"x": obj['x'],
|
193
|
+
"y": obj['y'],
|
194
|
+
"width": obj['width'],
|
195
|
+
"height": obj['height']
|
172
196
|
})
|
173
197
|
|
174
198
|
already_written = []
|
175
199
|
bounding_box = []
|
176
200
|
class_to_click = []
|
177
|
-
for i,
|
178
|
-
if
|
179
|
-
class_to_click.append(
|
201
|
+
for i, detected_class in enumerate(class_names):
|
202
|
+
if detected_class in already_written:
|
203
|
+
class_to_click.append(detected_class)
|
180
204
|
bounding_box.append(bounding_boxes[i])
|
181
|
-
index = already_written.index(
|
205
|
+
index = already_written.index(detected_class)
|
182
206
|
bounding_box.append(bounding_boxes[index])
|
183
207
|
|
184
|
-
already_written.append(
|
208
|
+
already_written.append(detected_class)
|
185
209
|
|
186
210
|
found = False
|
187
|
-
|
188
211
|
if len(class_to_click) == 1:
|
189
212
|
found = True
|
190
213
|
|
@@ -212,13 +235,14 @@ def click_on_objects(page, object_coords):
|
|
212
235
|
|
213
236
|
|
214
237
|
|
215
|
-
def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_vol='mix', schedule=None, day=None, copyrightcheck=False, suppressprint=False):
|
238
|
+
def upload_tiktok(video, description, accountname, hashtags=None, sound_name=None, sound_aud_vol='mix', schedule=None, day=None, copyrightcheck=False, suppressprint=False, headless=True):
|
216
239
|
|
217
240
|
"""
|
218
241
|
UPLOADS VIDEO TO TIKTOK
|
219
242
|
------------------------------------------------------------------------------------------------------------------------------------------------c
|
220
243
|
video (str) -> path to video to upload
|
221
244
|
description (str) -> description for video
|
245
|
+
accountname (str) -> account to upload on
|
222
246
|
hashtags (str)(array) -> hashtags for video
|
223
247
|
sound_name (str) -> name of tik tok sound to use for video
|
224
248
|
sound_aud_vol (str) -> volume of tik tok sound, 'main', 'mix' or 'background', check documentation for more info -> https://github.com/haziq-exe/TikTokAutoUploader
|
@@ -226,40 +250,51 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
|
|
226
250
|
day (int) -> day to schedule video for, check documentation for more info -> https://github.com/haziq-exe/TikTokAutoUploader
|
227
251
|
copyrightcheck (bool) -> include copyright check or not; CODE FAILS IF FAIL COPYRIGHT CHECK
|
228
252
|
suppressprint (bool) -> True means function doesnt print anything to provide updates on progress
|
253
|
+
headless (bool) -> run in headless mode or not
|
229
254
|
--------------------------------------------------------------------------------------------------------------------------------------------
|
230
255
|
"""
|
256
|
+
try:
|
257
|
+
check_for_updates()
|
258
|
+
except:
|
259
|
+
time.sleep(0.1)
|
231
260
|
|
232
261
|
retries = 0
|
233
262
|
cookie_read = False
|
234
263
|
oldQ = 'N.A'
|
235
264
|
|
236
|
-
if
|
237
|
-
|
238
|
-
|
265
|
+
if accountname == None:
|
266
|
+
sys.exit("PLEASE ENTER NAME OF ACCOUNT TO POST ON, READ DOCUMENTATION FOR MORE INFO")
|
267
|
+
|
268
|
+
if os.path.exists(f'TK_cookies_{accountname}.json'):
|
269
|
+
cookies, cookie_read = read_cookies(cookies_path=f'TK_cookies_{accountname}.json')
|
270
|
+
expired = check_expiry(accountname=accountname)
|
239
271
|
if expired == True:
|
240
|
-
os.remove('
|
241
|
-
print("COOKIES EXPIRED, PLEASE LOG-IN AGAIN")
|
272
|
+
os.remove(f'TK_cookies_{accountname}.json')
|
273
|
+
print(f"COOKIES EXPIRED FOR ACCOUNT {accountname}, PLEASE LOG-IN AGAIN")
|
242
274
|
cookie_read = False
|
243
275
|
|
244
276
|
if cookie_read == False:
|
245
277
|
install_js_dependencies()
|
246
|
-
login_warning()
|
278
|
+
login_warning(accountname=accountname)
|
247
279
|
result = run_javascript()
|
280
|
+
os.rename('TK_cookies.json', f'TK_cookies_{accountname}.json')
|
248
281
|
|
249
|
-
cookies, cookie_read = read_cookies("
|
282
|
+
cookies, cookie_read = read_cookies(f"TK_cookies_{accountname}.json")
|
250
283
|
if cookie_read == False:
|
251
284
|
sys.exit("ERROR READING COOKIES")
|
252
285
|
|
253
|
-
|
286
|
+
|
254
287
|
with sync_playwright() as p:
|
255
288
|
|
256
|
-
browser = p.
|
257
|
-
|
289
|
+
browser = p.firefox.launch(headless=headless)
|
258
290
|
context = browser.new_context()
|
259
291
|
context.add_cookies(cookies)
|
260
292
|
page = context.new_page()
|
261
293
|
url = 'https://www.tiktok.com/tiktokstudio/upload?from=upload&lang=en'
|
262
294
|
|
295
|
+
if suppressprint == False:
|
296
|
+
print(f"Uploading to account '{accountname}'")
|
297
|
+
|
263
298
|
while retries < 2:
|
264
299
|
try:
|
265
300
|
page.goto(url, timeout=30000)
|
@@ -298,7 +333,7 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
|
|
298
333
|
question = page.locator('div.VerifyBar___StyledDiv-sc-12zaxoy-0.hRJhHT').text_content()
|
299
334
|
if time.time() - start_time > 2:
|
300
335
|
break
|
301
|
-
if 'Select 2 objects that are the same' in question:
|
336
|
+
if 'Select 2 objects that are the same' in question or 'Select two objects that are the same' in question:
|
302
337
|
found = False
|
303
338
|
while found == False:
|
304
339
|
page.click('span.secsdk_captcha_refresh--text')
|
@@ -319,7 +354,10 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
|
|
319
354
|
image_width_real, image_height_real = image_size
|
320
355
|
|
321
356
|
webpage_coords = convert_to_webpage_coordinates(b_box, image_x, image_y, image_height_web, image_width_web, image_height_real, image_width_real)
|
357
|
+
if not webpage_coords:
|
358
|
+
webpage_coords.append((image_x + 50, image_y + 50))
|
322
359
|
click_on_objects(page, webpage_coords)
|
360
|
+
page.click("div.verify-captcha-submit-button")
|
323
361
|
time.sleep(0.5)
|
324
362
|
if attempts > 5:
|
325
363
|
sys.exit("FAILED TO SOLVE CAPTCHA")
|
@@ -327,6 +365,7 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
|
|
327
365
|
if page.locator("div.captcha_verify_message.captcha_verify_message-pass").is_visible():
|
328
366
|
solved = True
|
329
367
|
showedup = True
|
368
|
+
os.remove('captcha_image.jpg')
|
330
369
|
if page.locator("div.captcha_verify_message.captcha_verify_message-fail").is_visible():
|
331
370
|
showedup = True
|
332
371
|
oldQ = question
|
@@ -363,9 +402,11 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
|
|
363
402
|
image_width_real, image_height_real = image_size
|
364
403
|
|
365
404
|
webpage_coords = convert_to_webpage_coordinates(b_box, image_x, image_y, image_height_web, image_width_web, image_height_real, image_width_real)
|
366
|
-
|
405
|
+
if not webpage_coords:
|
406
|
+
webpage_coords.append((image_x + 50, image_y + 50))
|
367
407
|
click_on_objects(page, webpage_coords)
|
368
408
|
page.click("div.verify-captcha-submit-button")
|
409
|
+
time.sleep(1)
|
369
410
|
if attempts > 20:
|
370
411
|
sys.exit("FAILED TO SOLVE CAPTCHA")
|
371
412
|
showedup = False
|
@@ -431,13 +472,16 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
|
|
431
472
|
print("Description and Hashtags added")
|
432
473
|
|
433
474
|
try:
|
434
|
-
page.
|
475
|
+
page.wait_for_selector('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Post")[aria-disabled="false"]', timeout=12000000)
|
435
476
|
except:
|
436
477
|
sys.exit("ERROR: TIK TOK TOOK TOO LONG TO UPLOAD YOUR FILE (>20min). Try again, if issue persists then try a lower file size or different wifi connection")
|
437
478
|
|
438
479
|
time.sleep(0.2)
|
439
480
|
if suppressprint == False:
|
440
481
|
print("Tik tok done loading file onto servers")
|
482
|
+
|
483
|
+
if (schedule == None) and (day != None):
|
484
|
+
sys.exit("ERROR: CANT SCHEDULE FOR ANOTHER DAY USING 'day' WITHOUT ALSO INCLUDING TIME OF UPLOAD WITH 'schedule'; PLEASE ALSO INCLUDE TIME WITH 'schedule' PARAMETER")
|
441
485
|
|
442
486
|
if schedule != None:
|
443
487
|
try:
|
@@ -449,31 +493,39 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
|
|
449
493
|
except:
|
450
494
|
sys.exit("SCHEDULE TIME ERROR: PLEASE MAKE SURE YOUR SCHEDULE TIME IS A STRING THAT FOLLOWS THE 24H FORMAT 'HH:MM', VIDEO SAVED AS DRAFT")
|
451
495
|
|
452
|
-
page.locator('div.TUXRadioStandalone.TUXRadioStandalone--medium').
|
453
|
-
time.sleep(1)
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
time.sleep(0.
|
496
|
+
page.locator('div.TUXRadioStandalone.TUXRadioStandalone--medium:has(input[value="schedule"])').click()
|
497
|
+
# time.sleep(1)
|
498
|
+
visible = False
|
499
|
+
while visible == False:
|
500
|
+
if page.locator('button.TUXButton.TUXButton--default.TUXButton--medium.TUXButton--primary:has-text("Allow")').nth(0).is_visible():
|
501
|
+
page.locator('button.TUXButton.TUXButton--default.TUXButton--medium.TUXButton--primary:has-text("Allow")').nth(0).click()
|
502
|
+
visible = True
|
503
|
+
time.sleep(0.1)
|
504
|
+
else:
|
505
|
+
if page.locator('div.TUXTextInputCore-trailingIconWrapper').nth(1).is_visible():
|
506
|
+
visible = True
|
507
|
+
time.sleep(0.1)
|
460
508
|
if day != None:
|
461
|
-
page.locator('div.TUXTextInputCore-
|
509
|
+
page.locator('div.TUXTextInputCore-leadingIconWrapper:has(svg > path[d="M15 3a1 1 0 0 0-1 1v3h-1.4c-3.36 0-5.04 0-6.32.65a6 6 0 0 0-2.63 2.63C3 11.56 3 13.24 3 16.6v16.8c0 3.36 0 5.04.65 6.32a6 6 0 0 0 2.63 2.63c1.28.65 2.96.65 6.32.65h22.8c3.36 0 5.04 0 6.32-.65a6 6 0 0 0 2.63-2.63c.65-1.28.65-2.96.65-6.32V16.6c0-3.36 0-5.04-.65-6.32a6 6 0 0 0-2.63-2.63C40.44 7 38.76 7 35.4 7H34V4a1 1 0 0 0-1-1h-2a1 1 0 0 0-1 1v3H18V4a1 1 0 0 0-1-1h-2Zm-2.4 8H14v3a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1v-3h12v3a1 1 0 0 0 1 1h2a1 1 0 0 0 1-1v-3h1.4c1.75 0 2.82 0 3.62.07a5.11 5.11 0 0 1 .86.14h.03a2 2 0 0 1 .88.91 5.11 5.11 0 0 1 .14.86c.07.8.07 1.87.07 3.62v1.9H7v-1.9c0-1.75 0-2.82.07-3.62a5.12 5.12 0 0 1 .14-.86v-.03a2 2 0 0 1 .88-.87l.03-.01a5.11 5.11 0 0 1 .86-.14c.8-.07 1.87-.07 3.62-.07ZM7 22.5h34v10.9c0 1.75 0 2.82-.07 3.62a5.11 5.11 0 0 1-.14.86v.03a2 2 0 0 1-.88.87l-.03.01a5.11 5.11 0 0 1-.86.14c-.8.07-1.87.07-3.62.07H12.6c-1.75 0-2.82 0-3.62-.07a5.11 5.11 0 0 1-.89-.15 2 2 0 0 1-.87-.87l-.01-.03a5.12 5.12 0 0 1-.14-.86C7 36.22 7 35.15 7 33.4V22.5Z"])').click()
|
462
510
|
time.sleep(0.2)
|
463
511
|
try:
|
464
512
|
page.locator(f'span.day.valid:has-text("{day}")').click()
|
465
513
|
except:
|
466
514
|
sys.exit("SCHEDULE DAY ERROR: ERROR WITH SCHEDULED DAY, read documentation for more information on format of day")
|
467
515
|
try:
|
468
|
-
time.sleep(1)
|
469
|
-
page.locator('div.TUXTextInputCore-trailingIconWrapper').nth(0).click()
|
470
516
|
time.sleep(0.2)
|
471
|
-
page.locator(
|
517
|
+
page.locator('div.TUXTextInputCore-leadingIconWrapper:has(svg > path[d="M24 2a22 22 0 1 0 0 44 22 22 0 0 0 0-44ZM6 24a18 18 0 1 1 36 0 18 18 0 0 1-36 0Z"])').click()
|
518
|
+
time.sleep(0.2)
|
519
|
+
page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-right:has-text("{minute}")').scroll_into_view_if_needed()
|
472
520
|
time.sleep(0.2)
|
473
|
-
page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-right:has-text("{minute}")').
|
521
|
+
page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-right:has-text("{minute}")').click()
|
474
522
|
time.sleep(0.2)
|
475
|
-
page.locator(
|
476
|
-
|
523
|
+
if page.locator("div.tiktok-timepicker-time-picker-container").is_visible():
|
524
|
+
time.sleep(0.1)
|
525
|
+
else:
|
526
|
+
page.locator('div.TUXTextInputCore-leadingIconWrapper:has(svg > path[d="M24 2a22 22 0 1 0 0 44 22 22 0 0 0 0-44ZM6 24a18 18 0 1 1 36 0 18 18 0 0 1-36 0Z"])').click()
|
527
|
+
page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-left:has-text("{hour}")').scroll_into_view_if_needed()
|
528
|
+
page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-left:has-text("{hour}")').click()
|
477
529
|
time.sleep(1)
|
478
530
|
|
479
531
|
if suppressprint == False:
|
@@ -481,93 +533,14 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
|
|
481
533
|
|
482
534
|
except:
|
483
535
|
sys.exit("SCHEDULING ERROR: VIDEO SAVED AS DRAFT")
|
484
|
-
|
485
|
-
if (schedule == None) and (day != None):
|
486
|
-
sys.exit("ERROR: CANT SCHEDULE FOR ANOTHER DAY USING 'day' WITHOUT ALSO INCLUDING TIME OF UPLOAD WITH 'schedule'; PLEASE ALSO INCLUDE TIME WITH 'schedule' PARAMETER")
|
487
|
-
|
488
|
-
if(sound_name == None):
|
489
|
-
if copyrightcheck == True:
|
490
|
-
page.locator(".TUXSwitch-input").nth(0).click()
|
491
|
-
while copyrightcheck == True:
|
492
|
-
time.sleep(0.2)
|
493
|
-
if page.locator("span", has_text="No issues detected.").is_visible():
|
494
|
-
if suppressprint == False:
|
495
|
-
print("Copyright check complete")
|
496
|
-
break
|
497
|
-
if page.locator("span", has_text="Copyright issues detected.").is_visible():
|
498
|
-
sys.exit("COPYRIGHT CHECK FAILED: COPYRIGHT AUDIO DETECTED FROM TIKTOK")
|
499
|
-
|
500
|
-
if schedule == None:
|
501
|
-
page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Post")', timeout=10000)
|
502
|
-
uploaded = False
|
503
|
-
checks = 0
|
504
|
-
while uploaded == False:
|
505
|
-
if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
|
506
|
-
time.sleep(0.2)
|
507
|
-
break
|
508
|
-
time.sleep(0.2)
|
509
|
-
checks += 1
|
510
|
-
if checks > 100:
|
511
|
-
time.sleep(10)
|
512
|
-
if checks == 150:
|
513
|
-
break
|
514
|
-
else:
|
515
|
-
page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Schedule")', timeout=10000)
|
516
|
-
uploaded = False
|
517
|
-
checks = 0
|
518
|
-
while uploaded == False:
|
519
|
-
if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
|
520
|
-
time.sleep(0.2)
|
521
|
-
break
|
522
|
-
time.sleep(0.2)
|
523
|
-
checks += 1
|
524
|
-
if checks > 100:
|
525
|
-
time.sleep(10)
|
526
|
-
if checks == 150:
|
527
|
-
break
|
528
|
-
if suppressprint == False:
|
529
|
-
print("Done uploading video, NOTE: it may take a minute or two to show on TikTok")
|
530
|
-
|
531
|
-
page.close()
|
532
536
|
|
533
|
-
|
537
|
+
sound_fail = False
|
538
|
+
if sound_name != None:
|
534
539
|
try:
|
535
|
-
page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--secondary:has-text("Save draft")', timeout=10000)
|
536
|
-
except:
|
537
|
-
sys.exit("SAVE AS DRAFT BUTTON NOT FOUND; CANNOT ADD SOUND WITHOUT ABILITY TO SAVE DRAFTS")
|
538
|
-
|
539
|
-
time.sleep(0.5)
|
540
|
-
page.close()
|
541
|
-
|
542
|
-
browser = p.chromium.launch(headless=True)
|
543
|
-
|
544
|
-
context = browser.new_context()
|
545
|
-
context.add_cookies(cookies)
|
546
|
-
page = context.new_page()
|
547
|
-
url2 = 'https://www.tiktok.com/tiktokstudio/content?tab=draft'
|
548
|
-
|
549
|
-
while retries < 2:
|
550
|
-
try:
|
551
|
-
page.goto(url2, timeout=30000)
|
552
|
-
except:
|
553
|
-
retries +=1
|
554
|
-
time.sleep(5)
|
555
|
-
if retries == 2:
|
556
|
-
sys.exit("ERROR: TIK TOK PAGE FAILED TO LOAD, try again.")
|
557
|
-
else:
|
558
|
-
break
|
559
|
-
|
560
|
-
try:
|
561
|
-
page.wait_for_selector("path[d='M37.37 4.85a4.01 4.01 0 0 0-.99-.79 3 3 0 0 0-2.72 0c-.45.23-.81.6-1 .79a9 9 0 0 1-.04.05l-19.3 19.3c-1.64 1.63-2.53 2.52-3.35 3.47a36 36 0 0 0-4.32 6.16c-.6 1.1-1.14 2.24-2.11 4.33l-.3.6c-.4.75-.84 1.61-.8 2.43a2.5 2.5 0 0 0 2.37 2.36c.82.05 1.68-.4 2.44-.79l.59-.3c2.09-.97 3.23-1.5 4.33-2.11a36 36 0 0 0 6.16-4.32c.95-.82 1.84-1.71 3.47-3.34l19.3-19.3.05-.06a3 3 0 0 0 .78-3.71c-.22-.45-.6-.81-.78-1l-.02-.02-.03-.03-3.67-3.67a8.7 8.7 0 0 1-.06-.05ZM16.2 26.97 35.02 8.15l2.83 2.83L19.03 29.8c-1.7 1.7-2.5 2.5-3.33 3.21a32 32 0 0 1-7.65 4.93 32 32 0 0 1 4.93-7.65c.73-.82 1.51-1.61 3.22-3.32Z']")
|
562
|
-
page.click("path[d='M37.37 4.85a4.01 4.01 0 0 0-.99-.79 3 3 0 0 0-2.72 0c-.45.23-.81.6-1 .79a9 9 0 0 1-.04.05l-19.3 19.3c-1.64 1.63-2.53 2.52-3.35 3.47a36 36 0 0 0-4.32 6.16c-.6 1.1-1.14 2.24-2.11 4.33l-.3.6c-.4.75-.84 1.61-.8 2.43a2.5 2.5 0 0 0 2.37 2.36c.82.05 1.68-.4 2.44-.79l.59-.3c2.09-.97 3.23-1.5 4.33-2.11a36 36 0 0 0 6.16-4.32c.95-.82 1.84-1.71 3.47-3.34l19.3-19.3.05-.06a3 3 0 0 0 .78-3.71c-.22-.45-.6-.81-.78-1l-.02-.02-.03-.03-3.67-3.67a8.7 8.7 0 0 1-.06-.05ZM16.2 26.97 35.02 8.15l2.83 2.83L19.03 29.8c-1.7 1.7-2.5 2.5-3.33 3.21a32 32 0 0 1-7.65 4.93 32 32 0 0 1 4.93-7.65c.73-.82 1.51-1.61 3.22-3.32Z']")
|
563
|
-
page.wait_for_selector('div[data-contents="true"]')
|
564
|
-
page.wait_for_function("document.querySelector('.info-progress-num').textContent.trim() === '100%'", timeout=3000000)
|
565
|
-
time.sleep(0.2)
|
566
|
-
except:
|
567
|
-
sys.exit("ERROR ADDING SOUND: Video saved as draft")
|
568
|
-
|
569
|
-
if sound_name != None:
|
570
540
|
page.click("div.TUXButton-label:has-text('Edit video')")
|
541
|
+
except:
|
542
|
+
sound_fail = True
|
543
|
+
if sound_fail == False:
|
571
544
|
page.wait_for_selector("input.search-bar-input")
|
572
545
|
page.fill(f"input.search-bar-input", f"{sound_name}")
|
573
546
|
time.sleep(0.2)
|
@@ -620,11 +593,12 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
|
|
620
593
|
page.click("div.TUXButton-label:has-text('Save edit')")
|
621
594
|
if suppressprint == False:
|
622
595
|
print("Added sound")
|
623
|
-
|
596
|
+
|
597
|
+
if sound_fail == False:
|
624
598
|
page.wait_for_selector('div[data-contents="true"]')
|
625
599
|
|
626
600
|
if copyrightcheck == True:
|
627
|
-
page.
|
601
|
+
page.click('div.TUXSwitch:has(label.TUXSwitch-label:has-text("Run a copyright check")) input.TUXSwitch-input')
|
628
602
|
while copyrightcheck == True:
|
629
603
|
time.sleep(0.2)
|
630
604
|
if page.locator("span", has_text="No issues detected.").is_visible():
|
@@ -671,4 +645,148 @@ def upload_tiktok(video, description, hashtags=None, sound_name=None, sound_aud_
|
|
671
645
|
sys.exit("ERROR UPLOADING: VIDEO HAS SAVED AS DRAFT BUT CANT UPLOAD")
|
672
646
|
time.sleep(1)
|
673
647
|
|
674
|
-
page.close()
|
648
|
+
page.close()
|
649
|
+
else:
|
650
|
+
try:
|
651
|
+
page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--secondary:has-text("Save draft")', timeout=10000)
|
652
|
+
except:
|
653
|
+
sys.exit("SAVE AS DRAFT BUTTON NOT FOUND; Please try account that has ability to save as draft")
|
654
|
+
|
655
|
+
time.sleep(0.5)
|
656
|
+
page.close()
|
657
|
+
|
658
|
+
browser = p.chromium.launch(headless=headless)
|
659
|
+
|
660
|
+
context = browser.new_context()
|
661
|
+
context.add_cookies(cookies)
|
662
|
+
page = context.new_page()
|
663
|
+
url2 = 'https://www.tiktok.com/tiktokstudio/content?tab=draft'
|
664
|
+
|
665
|
+
while retries < 2:
|
666
|
+
try:
|
667
|
+
page.goto(url2, timeout=30000)
|
668
|
+
except:
|
669
|
+
retries +=1
|
670
|
+
time.sleep(5)
|
671
|
+
if retries == 2:
|
672
|
+
sys.exit("ERROR: TIK TOK PAGE FAILED TO LOAD, try again.")
|
673
|
+
else:
|
674
|
+
break
|
675
|
+
|
676
|
+
try:
|
677
|
+
page.wait_for_selector("path[d='M37.37 4.85a4.01 4.01 0 0 0-.99-.79 3 3 0 0 0-2.72 0c-.45.23-.81.6-1 .79a9 9 0 0 1-.04.05l-19.3 19.3c-1.64 1.63-2.53 2.52-3.35 3.47a36 36 0 0 0-4.32 6.16c-.6 1.1-1.14 2.24-2.11 4.33l-.3.6c-.4.75-.84 1.61-.8 2.43a2.5 2.5 0 0 0 2.37 2.36c.82.05 1.68-.4 2.44-.79l.59-.3c2.09-.97 3.23-1.5 4.33-2.11a36 36 0 0 0 6.16-4.32c.95-.82 1.84-1.71 3.47-3.34l19.3-19.3.05-.06a3 3 0 0 0 .78-3.71c-.22-.45-.6-.81-.78-1l-.02-.02-.03-.03-3.67-3.67a8.7 8.7 0 0 1-.06-.05ZM16.2 26.97 35.02 8.15l2.83 2.83L19.03 29.8c-1.7 1.7-2.5 2.5-3.33 3.21a32 32 0 0 1-7.65 4.93 32 32 0 0 1 4.93-7.65c.73-.82 1.51-1.61 3.22-3.32Z']")
|
678
|
+
page.click("path[d='M37.37 4.85a4.01 4.01 0 0 0-.99-.79 3 3 0 0 0-2.72 0c-.45.23-.81.6-1 .79a9 9 0 0 1-.04.05l-19.3 19.3c-1.64 1.63-2.53 2.52-3.35 3.47a36 36 0 0 0-4.32 6.16c-.6 1.1-1.14 2.24-2.11 4.33l-.3.6c-.4.75-.84 1.61-.8 2.43a2.5 2.5 0 0 0 2.37 2.36c.82.05 1.68-.4 2.44-.79l.59-.3c2.09-.97 3.23-1.5 4.33-2.11a36 36 0 0 0 6.16-4.32c.95-.82 1.84-1.71 3.47-3.34l19.3-19.3.05-.06a3 3 0 0 0 .78-3.71c-.22-.45-.6-.81-.78-1l-.02-.02-.03-.03-3.67-3.67a8.7 8.7 0 0 1-.06-.05ZM16.2 26.97 35.02 8.15l2.83 2.83L19.03 29.8c-1.7 1.7-2.5 2.5-3.33 3.21a32 32 0 0 1-7.65 4.93 32 32 0 0 1 4.93-7.65c.73-.82 1.51-1.61 3.22-3.32Z']")
|
679
|
+
page.wait_for_selector('div[data-contents="true"]')
|
680
|
+
time.sleep(0.2)
|
681
|
+
except:
|
682
|
+
sys.exit("ERROR ADDING SOUND: Video saved as draft")
|
683
|
+
|
684
|
+
if sound_name != None:
|
685
|
+
page.click("div.TUXButton-label:has-text('Edit video')")
|
686
|
+
page.wait_for_selector("input.search-bar-input")
|
687
|
+
page.fill(f"input.search-bar-input", f"{sound_name}")
|
688
|
+
time.sleep(0.2)
|
689
|
+
page.click("div.TUXButton-label:has-text('Search')")
|
690
|
+
try:
|
691
|
+
page.wait_for_selector('div.music-card-container')
|
692
|
+
page.click("div.music-card-container")
|
693
|
+
page.wait_for_selector("div.TUXButton-label:has-text('Use')")
|
694
|
+
page.click("div.TUXButton-label:has-text('Use')")
|
695
|
+
except:
|
696
|
+
sys.exit(f"ERROR: SOUND '{sound_name}' NOT FOUND")
|
697
|
+
try:
|
698
|
+
page.wait_for_selector('img[src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMSAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgNy41MDE2QzAgNi42NzMxNyAwLjY3MTU3MyA2LjAwMTYgMS41IDYuMDAxNkgzLjU3NzA5QzMuODY4MDUgNi4wMDE2IDQuMTQ0NTggNS44NzQ4OCA0LjMzNDU1IDUuNjU0NDlMOC43NDI1NSAwLjU0MDUyQzkuMzQ3OCAtMC4xNjE2NjggMTAuNSAwLjI2NjM3NCAxMC41IDEuMTkzNDFWMTguOTY3MkMxMC41IDE5Ljg3NDUgOS4zODg5NCAyMC4zMTI5IDguNzY5NDIgMTkuNjVMNC4zMzE3OSAxNC45MDIxQzQuMTQyNjkgMTQuNjk5OCAzLjg3ODE2IDE0LjU4NDkgMy42MDEyMiAxNC41ODQ5SDEuNUMwLjY3MTU3MyAxNC41ODQ5IDAgMTMuOTEzNCAwIDEzLjA4NDlWNy41MDE2Wk01Ljg0OTQ1IDYuOTYwMjdDNS4yNzk1NiA3LjYyMTQzIDQuNDQ5OTcgOC4wMDE2IDMuNTc3MDkgOC4wMDE2SDJWMTIuNTg0OUgzLjYwMTIyQzQuNDMyMDMgMTIuNTg0OSA1LjIyNTY0IDEyLjkyOTUgNS43OTI5NSAxMy41MzY0TDguNSAxNi40MzI4VjMuODg1MjJMNS44NDk0NSA2Ljk2MDI3WiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPHBhdGggZD0iTTEzLjUxNSA3LjE5MTE5QzEzLjM0MjQgNi45NzU1OSAxMy4zMzk5IDYuNjYwNTYgMTMuNTM1MiA2LjQ2NTNMMTQuMjQyMyA1Ljc1ODE5QzE0LjQzNzYgNS41NjI5MyAxNC43NTU4IDUuNTYxNzUgMTQuOTM1NiA1Ljc3MTM2QzE2Ljk5NTkgOC4xNzM2MiAxNi45OTU5IDExLjgyOCAxNC45MzU2IDE0LjIzMDNDMTQuNzU1OCAxNC40Mzk5IDE0LjQzNzYgMTQuNDM4NyAxNC4yNDIzIDE0LjI0MzVMMTMuNTM1MiAxMy41MzY0QzEzLjMzOTkgMTMuMzQxMSAxMy4zNDI0IDEzLjAyNjEgMTMuNTE1IDEyLjgxMDVDMTQuODEzIDExLjE4ODUgMTQuODEzIDguODEzMTIgMTMuNTE1IDcuMTkxMTlaIiBmaWxsPSIjMTYxODIzIiBmaWxsLW9wYWNpdHk9IjAuNiIvPgo8cGF0aCBkPSJNMTYuNzE3MiAxNi43MTgzQzE2LjUyMTkgMTYuNTIzMSAxNi41MjMxIDE2LjIwNzQgMTYuNzA3MiAxNi4wMDE3QzE5LjcyNTcgMTIuNjMgMTkuNzI1NyA3LjM3MTY4IDE2LjcwNzIgNC4wMDAwMUMxNi41MjMxIDMuNzk0MjcgMTYuNTIxOSAzLjQ3ODU4IDE2LjcxNzIgMy4yODMzMkwxNy40MjQzIDIuNTc2MjFDMTcuNjE5NSAyLjM4MDk1IDE3LjkzNyAyLjM4MDIgMTguMTIzMyAyLjU4NDA4QzIxLjkwOTkgNi43MjkyNiAyMS45MDk5IDEzLjI3MjQgMTguMTIzMyAxNy40MTc2QzE3LjkzNyAxNy42MjE1IDE3LjYxOTUgMTcuNjIwNyAxNy40MjQzIDE3LjQyNTVMMTYuNzE3MiAxNi43MTgzWiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPC9zdmc+Cg=="]')
|
699
|
+
page.click('img[src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMSAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgNy41MDE2QzAgNi42NzMxNyAwLjY3MTU3MyA2LjAwMTYgMS41IDYuMDAxNkgzLjU3NzA5QzMuODY4MDUgNi4wMDE2IDQuMTQ0NTggNS44NzQ4OCA0LjMzNDU1IDUuNjU0NDlMOC43NDI1NSAwLjU0MDUyQzkuMzQ3OCAtMC4xNjE2NjggMTAuNSAwLjI2NjM3NCAxMC41IDEuMTkzNDFWMTguOTY3MkMxMC41IDE5Ljg3NDUgOS4zODg5NCAyMC4zMTI5IDguNzY5NDIgMTkuNjVMNC4zMzE3OSAxNC45MDIxQzQuMTQyNjkgMTQuNjk5OCAzLjg3ODE2IDE0LjU4NDkgMy42MDEyMiAxNC41ODQ5SDEuNUMwLjY3MTU3MyAxNC41ODQ5IDAgMTMuOTEzNCAwIDEzLjA4NDlWNy41MDE2Wk01Ljg0OTQ1IDYuOTYwMjdDNS4yNzk1NiA3LjYyMTQzIDQuNDQ5OTcgOC4wMDE2IDMuNTc3MDkgOC4wMDE2SDJWMTIuNTg0OUgzLjYwMTIyQzQuNDMyMDMgMTIuNTg0OSA1LjIyNTY0IDEyLjkyOTUgNS43OTI5NSAxMy41MzY0TDguNSAxNi40MzI4VjMuODg1MjJMNS44NDk0NSA2Ljk2MDI3WiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPHBhdGggZD0iTTEzLjUxNSA3LjE5MTE5QzEzLjM0MjQgNi45NzU1OSAxMy4zMzk5IDYuNjYwNTYgMTMuNTM1MiA2LjQ2NTNMMTQuMjQyMyA1Ljc1ODE5QzE0LjQzNzYgNS41NjI5MyAxNC43NTU4IDUuNTYxNzUgMTQuOTM1NiA1Ljc3MTM2QzE2Ljk5NTkgOC4xNzM2MiAxNi45OTU5IDExLjgyOCAxNC45MzU2IDE0LjIzMDNDMTQuNzU1OCAxNC40Mzk5IDE0LjQzNzYgMTQuNDM4NyAxNC4yNDIzIDE0LjI0MzVMMTMuNTM1MiAxMy41MzY0QzEzLjMzOTkgMTMuMzQxMSAxMy4zNDI0IDEzLjAyNjEgMTMuNTE1IDEyLjgxMDVDMTQuODEzIDExLjE4ODUgMTQuODEzIDguODEzMTIgMTMuNTE1IDcuMTkxMTlaIiBmaWxsPSIjMTYxODIzIiBmaWxsLW9wYWNpdHk9IjAuNiIvPgo8cGF0aCBkPSJNMTYuNzE3MiAxNi43MTgzQzE2LjUyMTkgMTYuNTIzMSAxNi41MjMxIDE2LjIwNzQgMTYuNzA3MiAxNi4wMDE3QzE5LjcyNTcgMTIuNjMgMTkuNzI1NyA3LjM3MTY4IDE2LjcwNzIgNC4wMDAwMUMxNi41MjMxIDMuNzk0MjcgMTYuNTIxOSAzLjQ3ODU4IDE2LjcxNzIgMy4yODMzMkwxNy40MjQzIDIuNTc2MjFDMTcuNjE5NSAyLjM4MDk1IDE3LjkzNyAyLjM4MDIgMTguMTIzMyAyLjU4NDA4QzIxLjkwOTkgNi43MjkyNiAyMS45MDk5IDEzLjI3MjQgMTguMTIzMyAxNy40MTc2QzE3LjkzNyAxNy42MjE1IDE3LjYxOTUgMTcuNjIwNyAxNy40MjQzIDE3LjQyNTVMMTYuNzE3MiAxNi43MTgzWiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPC9zdmc+Cg=="]')
|
700
|
+
time.sleep(0.5)
|
701
|
+
sliders = page.locator("input.scaleInput")
|
702
|
+
|
703
|
+
if sound_aud_vol == 'background':
|
704
|
+
slider1 = sliders.nth(0)
|
705
|
+
bounding_box1 = slider1.bounding_box()
|
706
|
+
if bounding_box1:
|
707
|
+
x1 = bounding_box1["x"] + (bounding_box1["width"] * 0.92)
|
708
|
+
y1 = bounding_box1["y"] + bounding_box1["height"] / 2
|
709
|
+
page.mouse.click(x1, y1)
|
710
|
+
|
711
|
+
slider2 = sliders.nth(1)
|
712
|
+
bounding_box2 = slider2.bounding_box()
|
713
|
+
if bounding_box2:
|
714
|
+
x2 = bounding_box2["x"] + (bounding_box2["width"] * 0.097)
|
715
|
+
y2 = bounding_box2["y"] + bounding_box2["height"] / 2
|
716
|
+
page.mouse.click(x2, y2)
|
717
|
+
|
718
|
+
if sound_aud_vol == 'main':
|
719
|
+
slider1 = sliders.nth(0)
|
720
|
+
bounding_box1 = slider1.bounding_box()
|
721
|
+
if bounding_box1:
|
722
|
+
x1 = bounding_box1["x"] + (bounding_box1["width"] * 0.092)
|
723
|
+
y1 = bounding_box1["y"] + bounding_box1["height"] / 2
|
724
|
+
page.mouse.click(x1, y1)
|
725
|
+
slider2 = sliders.nth(1)
|
726
|
+
bounding_box2 = slider2.bounding_box()
|
727
|
+
if bounding_box2:
|
728
|
+
x2 = bounding_box2["x"] + (bounding_box2["width"] * 0.92)
|
729
|
+
y2 = bounding_box2["y"] + bounding_box2["height"] / 2
|
730
|
+
page.mouse.click(x2, y2)
|
731
|
+
except:
|
732
|
+
sys.exit("ERROR ADJUSTING SOUND VOLUME: please try again.")
|
733
|
+
|
734
|
+
page.wait_for_selector("div.TUXButton-label:has-text('Save edit')")
|
735
|
+
page.click("div.TUXButton-label:has-text('Save edit')")
|
736
|
+
if suppressprint == False:
|
737
|
+
print("Added sound")
|
738
|
+
|
739
|
+
|
740
|
+
page.wait_for_selector('div[data-contents="true"]')
|
741
|
+
|
742
|
+
if copyrightcheck == True:
|
743
|
+
page.click('div.TUXSwitch:has(label.TUXSwitch-label:has-text("Run a copyright check")) input.TUXSwitch-input')
|
744
|
+
while copyrightcheck == True:
|
745
|
+
time.sleep(0.2)
|
746
|
+
if page.locator("span", has_text="No issues detected.").is_visible():
|
747
|
+
if suppressprint == False:
|
748
|
+
print("Copyright check complete")
|
749
|
+
break
|
750
|
+
if page.locator("span", has_text="Copyright issues detected.").is_visible():
|
751
|
+
sys.exit("COPYRIGHT CHECK FAILED: VIDEO SAVED AS DRAFT, COPYRIGHT AUDIO DETECTED FROM TIKTOK")
|
752
|
+
|
753
|
+
|
754
|
+
try:
|
755
|
+
if schedule == None:
|
756
|
+
page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Post")', timeout=10000)
|
757
|
+
uploaded = False
|
758
|
+
checks = 0
|
759
|
+
while uploaded == False:
|
760
|
+
if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
|
761
|
+
time.sleep(0.2)
|
762
|
+
break
|
763
|
+
time.sleep(0.2)
|
764
|
+
checks += 1
|
765
|
+
if checks > 100:
|
766
|
+
time.sleep(10)
|
767
|
+
if checks == 150:
|
768
|
+
break
|
769
|
+
else:
|
770
|
+
page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Schedule")', timeout=10000)
|
771
|
+
uploaded = False
|
772
|
+
checks = 0
|
773
|
+
while uploaded == False:
|
774
|
+
if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
|
775
|
+
time.sleep(0.2)
|
776
|
+
break
|
777
|
+
time.sleep(0.2)
|
778
|
+
checks += 1
|
779
|
+
if checks > 100:
|
780
|
+
time.sleep(10)
|
781
|
+
if checks == 150:
|
782
|
+
break
|
783
|
+
if suppressprint == False:
|
784
|
+
print("Done uploading video, NOTE: it may take a minute or two to show on TikTok")
|
785
|
+
except:
|
786
|
+
time.sleep(5)
|
787
|
+
sys.exit("ERROR UPLOADING: VIDEO HAS SAVED AS DRAFT BUT CANT UPLOAD")
|
788
|
+
time.sleep(1)
|
789
|
+
|
790
|
+
page.close()
|
791
|
+
|
792
|
+
return "Completed"
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: tiktokautouploader
|
3
|
-
Version: 2
|
3
|
+
Version: 3.2
|
4
4
|
Summary: Upload or schedule videos to TikTok with viral TikTok sounds and hashtags.
|
5
5
|
Project-URL: Homepage, https://github.com/haziq-exe/TikTokAutoUploader
|
6
6
|
Author-email: HAZIQ <haziqmk123@gmail.com>
|
@@ -29,9 +29,8 @@ Description-Content-Type: text/markdown
|
|
29
29
|
|
30
30
|
[](https://pypi.org/project/tiktokautouploader/) [](https://opensource.org/licenses/MIT)
|
31
31
|
|
32
|
-
|
33
32
|
<p align="center">
|
34
|
-
<img src="READMEimage/
|
33
|
+
<img src="READMEimage/READMEGIF.gif" alt="" width="900"/>
|
35
34
|
</p>
|
36
35
|
|
37
36
|
## 🚀 Features
|
@@ -41,7 +40,10 @@ Description-Content-Type: text/markdown
|
|
41
40
|
- **🗓 Schedule Uploads:** Upload videos at specific times or upto 10 days in advance with our scheduling feature.
|
42
41
|
- **🔍 Copyright Check:** Ensure your video is safe from copyright claims before uploading.
|
43
42
|
- **🏷 Add Working Hashtags:** Increase your reach by adding effective hashtags that actually work.
|
43
|
+
- **⏰ Cutdown on upload time:** Upload to TikTok with way less hassle and much more speed using our library.
|
44
|
+
- **📝 Upload to different accounts:** Stay organized and on top of multiple different accounts with our multi-account functionality.
|
44
45
|
|
46
|
+
⭐️ If you like this project please feel free to star it, Thank you.
|
45
47
|
|
46
48
|
## 📦 Installation
|
47
49
|
|
@@ -51,6 +53,8 @@ Description-Content-Type: text/markdown
|
|
51
53
|
pip install tiktokautouploader
|
52
54
|
```
|
53
55
|
|
56
|
+
**NOTE:** IF YOU HAVE INSTALLED BEFORE, PLEASE MAKE SURE YOU UPGRADE TO THE LATEST VERSION.
|
57
|
+
|
54
58
|
---
|
55
59
|
|
56
60
|
## ⚙️ Pre-requisites
|
@@ -60,7 +64,7 @@ pip install tiktokautouploader
|
|
60
64
|
- **Note:** The necessary JavaScript dependencies (`playwright`,`playwright-extra`, `puppeteer-extra-plugin-stealth`) will be AUTOMATICALLY installed the first time you run the function, so you don't need to install them manually. Make sure that `npm` (Node.js package manager) is available in your system's PATH.
|
61
65
|
|
62
66
|
|
63
|
-
2. **Browser Binaries:** If you don't have them already, you'll need to install the browser binaries for `playwright`.
|
67
|
+
2. **Browser Binaries:** If you don't have them already, you'll need to install the browser binaries for `playwright`. This library uses chromium and firefox.
|
64
68
|
|
65
69
|
to do so, just run the following command AFTER installing the package:
|
66
70
|
|
@@ -68,11 +72,13 @@ pip install tiktokautouploader
|
|
68
72
|
python -m playwright install
|
69
73
|
```
|
70
74
|
|
75
|
+
**NOTE:** If you want to add sounds to your TikTok, you MUST have the ability to save drafts. If you don't want to add sounds then you don't need this feature.
|
76
|
+
|
71
77
|
|
72
78
|
## 📝 Quick-Start
|
73
79
|
|
74
80
|
**NOTE:** It is highly recommended you read DOCUMENTATION.md before using the library.
|
75
|
-
The first time you run the code, you will be prompted to log-in, this will only occur the first time the function is used. Check documentation for more info.
|
81
|
+
The first time you run the code for an account, you will be prompted to log-in, this will only occur the first time the function is used for the account. Check documentation for more info.
|
76
82
|
|
77
83
|
## Upload with hashtags
|
78
84
|
|
@@ -81,16 +87,17 @@ from tiktokautouploader import upload_tiktok
|
|
81
87
|
|
82
88
|
video_path = 'path/to/your/video.mp4'
|
83
89
|
description = 'Check out my latest TikTok video!'
|
90
|
+
accountname = 'mytiktokaccount'
|
84
91
|
hashtags = ['#fun', '#viral']
|
85
92
|
|
86
|
-
upload_tiktok(video=video_path, description=description, hashtags=hashtags)
|
93
|
+
upload_tiktok(video=video_path, description=description, accountname=accountname, hashtags=hashtags)
|
87
94
|
|
88
95
|
```
|
89
96
|
|
90
97
|
### Upload with TikTok Sound
|
91
98
|
|
92
99
|
```python
|
93
|
-
upload_tiktok(video=video_path, description=description, sound_name='trending_sound', sound_aud_vol='main')
|
100
|
+
upload_tiktok(video=video_path, description=description, accountname=accountname, sound_name='trending_sound', sound_aud_vol='main')
|
94
101
|
```
|
95
102
|
|
96
103
|
PLEASE READ DOCUMENTATION FOR MORE INFO.
|
@@ -98,7 +105,7 @@ PLEASE READ DOCUMENTATION FOR MORE INFO.
|
|
98
105
|
### Schedule an Upload
|
99
106
|
|
100
107
|
```python
|
101
|
-
upload_tiktok(video=video_path, description=description, schedule='03:10', day=11)
|
108
|
+
upload_tiktok(video=video_path, description=description, accountname=accountname, schedule='03:10', day=11)
|
102
109
|
```
|
103
110
|
|
104
111
|
PLEASE READ DOCUMENTATION FOR MORE INFO
|
@@ -106,16 +113,17 @@ PLEASE READ DOCUMENTATION FOR MORE INFO
|
|
106
113
|
### Perform Copyright Check Before Uploading
|
107
114
|
|
108
115
|
```python
|
109
|
-
upload_tiktok(video=video_path, description=description, hashtags=hashtags, copyrightcheck=True)
|
116
|
+
upload_tiktok(video=video_path, description=description, accountname=accountname, hashtags=hashtags, copyrightcheck=True)
|
110
117
|
```
|
111
118
|
|
112
119
|
## 🎯 Why Choose `autotiktokuploader`?
|
113
120
|
|
114
121
|
- **No more captchas:** Fully automated uploads without interruptions, If captchas do show up, no worries, they will be solved. (read documentation for more info)
|
115
|
-
- **Maximize your reach:** Add popular sounds and effective hashtags that work to boost visibility
|
122
|
+
- **Maximize your reach:** Add popular sounds and effective hashtags that work to boost visibility and go viral!
|
116
123
|
- **Stay compliant:** Built-in copyright checks to avoid unforeseen takedowns.
|
117
|
-
- **Convenient scheduling:** Post at the right time, even when you're away
|
124
|
+
- **Convenient scheduling:** Post at the right time, even when you're away!
|
118
125
|
- **Much faster than manually uploading:** Drastically reduce the time you need to upload videos, just click one button and be done much quicker!
|
126
|
+
- **Upload to different account:** Stay on top of all your TikTok accounts with our multi-account functionality!
|
119
127
|
|
120
128
|
## 🛠 Dependencies
|
121
129
|
|
@@ -136,4 +144,10 @@ Created by **Haziq**. Feel free to reach out at [haziqmk123@gmail.com](mailto:ha
|
|
136
144
|
## 📄 License
|
137
145
|
|
138
146
|
This project is licensed under the MIT License. See the [LICENSE](LICENSE.md) file for details.
|
139
|
-
|
147
|
+
|
148
|
+
## 📮 Related Projects
|
149
|
+
|
150
|
+
If you liked this project please check out my use case showcase project that generates TikToks and uploads them using 'tiktokautouploader'
|
151
|
+
|
152
|
+
[TikTokGenerator](https://github.com/haziq-exe/TikTokGenerator)
|
153
|
+
|
@@ -0,0 +1,7 @@
|
|
1
|
+
tiktokautouploader/__init__.py,sha256=u7OWCK_u68ST8dfrkSF4Yw44CJOzV9NXI6ASRuoDfmE,64
|
2
|
+
tiktokautouploader/function.py,sha256=m7ynv_zKtac1-wRSK2hndxevh1mUJCb0KZx8oFObz1c,44875
|
3
|
+
tiktokautouploader/Js_assets/login.js,sha256=SLhtPYo8ZfTRUnbR7Xqp084lSuAOqIWUxi75FlFH3vs,966
|
4
|
+
tiktokautouploader-3.2.dist-info/METADATA,sha256=kVxGqGPeVhibiiHayhz1KRRjMfbIyQ2yBvMAmL73zUg,6161
|
5
|
+
tiktokautouploader-3.2.dist-info/WHEEL,sha256=fl6v0VwpzfGBVsGtkAkhILUlJxROXbA3HvRL6Fe3140,105
|
6
|
+
tiktokautouploader-3.2.dist-info/licenses/LICENSE.md,sha256=hYds_VJIpnS5gC73WhuWk2IY_e9BWjuEJthQCb9ThyU,1073
|
7
|
+
tiktokautouploader-3.2.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
tiktokautouploader/__init__.py,sha256=u7OWCK_u68ST8dfrkSF4Yw44CJOzV9NXI6ASRuoDfmE,64
|
2
|
-
tiktokautouploader/function.py,sha256=PhHDU2GqteX5MqsPYQiyYfT09XHbLSG3_ydH9j4QHJE,33619
|
3
|
-
tiktokautouploader/Js_assets/login.js,sha256=SLhtPYo8ZfTRUnbR7Xqp084lSuAOqIWUxi75FlFH3vs,966
|
4
|
-
tiktokautouploader-2.95.dist-info/METADATA,sha256=5fJDsAptfF53htSHKekKk8JGcoWdrS58LS-sucWOj30,5033
|
5
|
-
tiktokautouploader-2.95.dist-info/WHEEL,sha256=fl6v0VwpzfGBVsGtkAkhILUlJxROXbA3HvRL6Fe3140,105
|
6
|
-
tiktokautouploader-2.95.dist-info/licenses/LICENSE.md,sha256=hYds_VJIpnS5gC73WhuWk2IY_e9BWjuEJthQCb9ThyU,1073
|
7
|
-
tiktokautouploader-2.95.dist-info/RECORD,,
|
File without changes
|
File without changes
|