tiktokautouploader 2.98__py2.py3-none-any.whl → 3.3__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.
@@ -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
@@ -139,21 +139,27 @@ def download_image(image_url):
139
139
  f.write(response.content)
140
140
  return image_path
141
141
 
142
-
143
142
  def run_inference_on_image_tougher(image_path, object):
144
143
 
145
- model = inference.get_model("captcha-2-6ehbe/2")
146
- results = model.infer(image=image_path)
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")
147
153
 
148
154
  class_names = []
149
155
  bounding_boxes = []
150
- for obj in results[0].predictions:
151
- class_names.append(obj.class_name)
156
+ for obj in results['predictions']:
157
+ class_names.append(obj['class'])
152
158
  bounding_boxes.append({
153
- "x": obj.x,
154
- "y": obj.y,
155
- "width": obj.width,
156
- "height": obj.height
159
+ "x": obj['x'],
160
+ "y": obj['y'],
161
+ "width": obj['width'],
162
+ "height": obj['height']
157
163
  })
158
164
 
159
165
  bounding_box = []
@@ -168,34 +174,40 @@ def run_inference_on_image_tougher(image_path, object):
168
174
 
169
175
  def run_inference_on_image(image_path):
170
176
 
171
- model = inference.get_model("tk-3nwi9/2")
172
- results = model.infer(image=image_path)
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")
173
186
 
174
187
  class_names = []
175
188
  bounding_boxes = []
176
- for obj in results[0].predictions:
177
- class_names.append(obj.class_name)
189
+ for obj in results['predictions']:
190
+ class_names.append(obj['class'])
178
191
  bounding_boxes.append({
179
- "x": obj.x,
180
- "y": obj.y,
181
- "width": obj.width,
182
- "height": obj.height
192
+ "x": obj['x'],
193
+ "y": obj['y'],
194
+ "width": obj['width'],
195
+ "height": obj['height']
183
196
  })
184
197
 
185
198
  already_written = []
186
199
  bounding_box = []
187
200
  class_to_click = []
188
- for i, classes in enumerate(class_names):
189
- if classes in already_written:
190
- class_to_click.append(classes)
201
+ for i, detected_class in enumerate(class_names):
202
+ if detected_class in already_written:
203
+ class_to_click.append(detected_class)
191
204
  bounding_box.append(bounding_boxes[i])
192
- index = already_written.index(classes)
205
+ index = already_written.index(detected_class)
193
206
  bounding_box.append(bounding_boxes[index])
194
207
 
195
- already_written.append(classes)
208
+ already_written.append(detected_class)
196
209
 
197
210
  found = False
198
-
199
211
  if len(class_to_click) == 1:
200
212
  found = True
201
213
 
@@ -223,13 +235,14 @@ def click_on_objects(page, object_coords):
223
235
 
224
236
 
225
237
 
226
- def upload_tiktok(video, description, accountname, 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):
227
239
 
228
240
  """
229
241
  UPLOADS VIDEO TO TIKTOK
230
242
  ------------------------------------------------------------------------------------------------------------------------------------------------c
231
243
  video (str) -> path to video to upload
232
244
  description (str) -> description for video
245
+ accountname (str) -> account to upload on
233
246
  hashtags (str)(array) -> hashtags for video
234
247
  sound_name (str) -> name of tik tok sound to use for video
235
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
@@ -237,6 +250,7 @@ def upload_tiktok(video, description, accountname, hashtags=None, sound_name=Non
237
250
  day (int) -> day to schedule video for, check documentation for more info -> https://github.com/haziq-exe/TikTokAutoUploader
238
251
  copyrightcheck (bool) -> include copyright check or not; CODE FAILS IF FAIL COPYRIGHT CHECK
239
252
  suppressprint (bool) -> True means function doesnt print anything to provide updates on progress
253
+ headless (bool) -> run in headless mode or not
240
254
  --------------------------------------------------------------------------------------------------------------------------------------------
241
255
  """
242
256
  try:
@@ -272,8 +286,7 @@ def upload_tiktok(video, description, accountname, hashtags=None, sound_name=Non
272
286
 
273
287
  with sync_playwright() as p:
274
288
 
275
- browser = p.firefox.launch(headless=True)
276
-
289
+ browser = p.firefox.launch(headless=headless)
277
290
  context = browser.new_context()
278
291
  context.add_cookies(cookies)
279
292
  page = context.new_page()
@@ -459,13 +472,16 @@ def upload_tiktok(video, description, accountname, hashtags=None, sound_name=Non
459
472
  print("Description and Hashtags added")
460
473
 
461
474
  try:
462
- page.wait_for_function("document.querySelector('.info-progress-num').textContent.trim() === '100%'", timeout=12000000)
475
+ page.wait_for_selector('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Post")[aria-disabled="false"]', timeout=12000000)
463
476
  except:
464
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")
465
478
 
466
479
  time.sleep(0.2)
467
480
  if suppressprint == False:
468
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")
469
485
 
470
486
  if schedule != None:
471
487
  try:
@@ -477,31 +493,39 @@ def upload_tiktok(video, description, accountname, hashtags=None, sound_name=Non
477
493
  except:
478
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")
479
495
 
480
- page.locator('div.TUXRadioStandalone.TUXRadioStandalone--medium').nth(1).click()
481
- time.sleep(1)
482
- if page.locator('button.TUXButton.TUXButton--default.TUXButton--medium.TUXButton--primary:has-text("Allow")').nth(0).is_visible():
483
- page.locator('button.TUXButton.TUXButton--default.TUXButton--medium.TUXButton--primary:has-text("Allow")').nth(0).click()
484
- time.sleep(0.2)
485
- else:
486
- if page.locator('div.TUXTextInputCore-trailingIconWrapper').nth(1).is_visible():
487
- time.sleep(0.2)
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)
488
508
  if day != None:
489
- page.locator('div.TUXTextInputCore-trailingIconWrapper').nth(1).click()
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()
490
510
  time.sleep(0.2)
491
511
  try:
492
512
  page.locator(f'span.day.valid:has-text("{day}")').click()
493
513
  except:
494
514
  sys.exit("SCHEDULE DAY ERROR: ERROR WITH SCHEDULED DAY, read documentation for more information on format of day")
495
515
  try:
496
- time.sleep(1)
497
- page.locator('div.TUXTextInputCore-trailingIconWrapper').nth(0).click()
498
516
  time.sleep(0.2)
499
- page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-right:has-text("{minute}")').nth(0).scroll_into_view_if_needed()
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()
500
520
  time.sleep(0.2)
501
- page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-right:has-text("{minute}")').nth(0).click()
521
+ page.locator(f'.tiktok-timepicker-option-text.tiktok-timepicker-right:has-text("{minute}")').click()
502
522
  time.sleep(0.2)
503
- page.locator(f'.tiktok-timepicker-option-text:has-text("{hour}")').nth(0).scroll_into_view_if_needed()
504
- page.locator(f'.tiktok-timepicker-option-text:has-text("{hour}")').nth(0).click()
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()
505
529
  time.sleep(1)
506
530
 
507
531
  if suppressprint == False:
@@ -509,93 +533,14 @@ def upload_tiktok(video, description, accountname, hashtags=None, sound_name=Non
509
533
 
510
534
  except:
511
535
  sys.exit("SCHEDULING ERROR: VIDEO SAVED AS DRAFT")
512
-
513
- if (schedule == None) and (day != None):
514
- 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")
515
536
 
516
- if(sound_name == None):
517
- if copyrightcheck == True:
518
- page.locator(".TUXSwitch-input").nth(0).click()
519
- while copyrightcheck == True:
520
- time.sleep(0.2)
521
- if page.locator("span", has_text="No issues detected.").is_visible():
522
- if suppressprint == False:
523
- print("Copyright check complete")
524
- break
525
- if page.locator("span", has_text="Copyright issues detected.").is_visible():
526
- sys.exit("COPYRIGHT CHECK FAILED: COPYRIGHT AUDIO DETECTED FROM TIKTOK")
527
-
528
- if schedule == None:
529
- page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Post")', timeout=10000)
530
- uploaded = False
531
- checks = 0
532
- while uploaded == False:
533
- if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
534
- time.sleep(0.2)
535
- break
536
- time.sleep(0.2)
537
- checks += 1
538
- if checks > 100:
539
- time.sleep(10)
540
- if checks == 150:
541
- break
542
- else:
543
- page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Schedule")', timeout=10000)
544
- uploaded = False
545
- checks = 0
546
- while uploaded == False:
547
- if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
548
- time.sleep(0.2)
549
- break
550
- time.sleep(0.2)
551
- checks += 1
552
- if checks > 100:
553
- time.sleep(10)
554
- if checks == 150:
555
- break
556
- if suppressprint == False:
557
- print("Done uploading video, NOTE: it may take a minute or two to show on TikTok")
558
-
559
- page.close()
560
-
561
- else:
562
- try:
563
- page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--secondary:has-text("Save draft")', timeout=10000)
564
- except:
565
- sys.exit("SAVE AS DRAFT BUTTON NOT FOUND; CANNOT ADD SOUND WITHOUT ABILITY TO SAVE DRAFTS")
566
-
567
- time.sleep(0.5)
568
- page.close()
569
-
570
- browser = p.chromium.launch(headless=True)
571
-
572
- context = browser.new_context()
573
- context.add_cookies(cookies)
574
- page = context.new_page()
575
- url2 = 'https://www.tiktok.com/tiktokstudio/content?tab=draft'
576
-
577
- while retries < 2:
578
- try:
579
- page.goto(url2, timeout=30000)
580
- except:
581
- retries +=1
582
- time.sleep(5)
583
- if retries == 2:
584
- sys.exit("ERROR: TIK TOK PAGE FAILED TO LOAD, try again.")
585
- else:
586
- break
587
-
537
+ sound_fail = False
538
+ if sound_name != None:
588
539
  try:
589
- 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']")
590
- 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']")
591
- page.wait_for_selector('div[data-contents="true"]')
592
- page.wait_for_function("document.querySelector('.info-progress-num').textContent.trim() === '100%'", timeout=3000000)
593
- time.sleep(0.2)
594
- except:
595
- sys.exit("ERROR ADDING SOUND: Video saved as draft")
596
-
597
- if sound_name != None:
598
540
  page.click("div.TUXButton-label:has-text('Edit video')")
541
+ except:
542
+ sound_fail = True
543
+ if sound_fail == False:
599
544
  page.wait_for_selector("input.search-bar-input")
600
545
  page.fill(f"input.search-bar-input", f"{sound_name}")
601
546
  time.sleep(0.2)
@@ -648,11 +593,12 @@ def upload_tiktok(video, description, accountname, hashtags=None, sound_name=Non
648
593
  page.click("div.TUXButton-label:has-text('Save edit')")
649
594
  if suppressprint == False:
650
595
  print("Added sound")
651
-
596
+
597
+ if sound_fail == False:
652
598
  page.wait_for_selector('div[data-contents="true"]')
653
599
 
654
600
  if copyrightcheck == True:
655
- page.locator(".TUXSwitch-input").nth(0).click()
601
+ page.click('div.TUXSwitch:has(label.TUXSwitch-label:has-text("Run a copyright check")) input.TUXSwitch-input')
656
602
  while copyrightcheck == True:
657
603
  time.sleep(0.2)
658
604
  if page.locator("span", has_text="No issues detected.").is_visible():
@@ -670,13 +616,11 @@ def upload_tiktok(video, description, accountname, hashtags=None, sound_name=Non
670
616
  checks = 0
671
617
  while uploaded == False:
672
618
  if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
673
- time.sleep(0.2)
619
+ time.sleep(0.1)
674
620
  break
675
621
  time.sleep(0.2)
676
622
  checks += 1
677
- if checks > 100:
678
- time.sleep(10)
679
- if checks == 150:
623
+ if checks == 25:
680
624
  break
681
625
  else:
682
626
  page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Schedule")', timeout=10000)
@@ -688,15 +632,153 @@ def upload_tiktok(video, description, accountname, hashtags=None, sound_name=Non
688
632
  break
689
633
  time.sleep(0.2)
690
634
  checks += 1
691
- if checks > 100:
692
- time.sleep(10)
693
- if checks == 150:
635
+ if checks == 25:
694
636
  break
695
637
  if suppressprint == False:
696
638
  print("Done uploading video, NOTE: it may take a minute or two to show on TikTok")
697
639
  except:
698
- time.sleep(5)
699
- sys.exit("ERROR UPLOADING: VIDEO HAS SAVED AS DRAFT BUT CANT UPLOAD")
640
+ time.sleep(2)
641
+ sys.exit("POSSIBLE ERROR UPLOADING: Cannot confirm if uploaded successfully, Please check account in a minute or two to confirm.")
700
642
  time.sleep(1)
701
643
 
702
- page.close()
644
+ page.close()
645
+ else:
646
+ try:
647
+ page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--secondary:has-text("Save draft")', timeout=10000)
648
+ except:
649
+ sys.exit("SAVE AS DRAFT BUTTON NOT FOUND; Please try account that has ability to save as draft")
650
+
651
+ time.sleep(0.5)
652
+ page.close()
653
+
654
+ browser = p.chromium.launch(headless=headless)
655
+
656
+ context = browser.new_context()
657
+ context.add_cookies(cookies)
658
+ page = context.new_page()
659
+ url2 = 'https://www.tiktok.com/tiktokstudio/content?tab=draft'
660
+
661
+ while retries < 2:
662
+ try:
663
+ page.goto(url2, timeout=30000)
664
+ except:
665
+ retries +=1
666
+ time.sleep(5)
667
+ if retries == 2:
668
+ sys.exit("ERROR: TIK TOK PAGE FAILED TO LOAD, try again.")
669
+ else:
670
+ break
671
+
672
+ try:
673
+ 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']")
674
+ 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']")
675
+ page.wait_for_selector('div[data-contents="true"]')
676
+ time.sleep(0.2)
677
+ except:
678
+ sys.exit("ERROR ADDING SOUND: Video saved as draft")
679
+
680
+ if sound_name != None:
681
+ page.click("div.TUXButton-label:has-text('Edit video')")
682
+ page.wait_for_selector("input.search-bar-input")
683
+ page.fill(f"input.search-bar-input", f"{sound_name}")
684
+ time.sleep(0.2)
685
+ page.click("div.TUXButton-label:has-text('Search')")
686
+ try:
687
+ page.wait_for_selector('div.music-card-container')
688
+ page.click("div.music-card-container")
689
+ page.wait_for_selector("div.TUXButton-label:has-text('Use')")
690
+ page.click("div.TUXButton-label:has-text('Use')")
691
+ except:
692
+ sys.exit(f"ERROR: SOUND '{sound_name}' NOT FOUND")
693
+ try:
694
+ page.wait_for_selector('img[src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMSAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgNy41MDE2QzAgNi42NzMxNyAwLjY3MTU3MyA2LjAwMTYgMS41IDYuMDAxNkgzLjU3NzA5QzMuODY4MDUgNi4wMDE2IDQuMTQ0NTggNS44NzQ4OCA0LjMzNDU1IDUuNjU0NDlMOC43NDI1NSAwLjU0MDUyQzkuMzQ3OCAtMC4xNjE2NjggMTAuNSAwLjI2NjM3NCAxMC41IDEuMTkzNDFWMTguOTY3MkMxMC41IDE5Ljg3NDUgOS4zODg5NCAyMC4zMTI5IDguNzY5NDIgMTkuNjVMNC4zMzE3OSAxNC45MDIxQzQuMTQyNjkgMTQuNjk5OCAzLjg3ODE2IDE0LjU4NDkgMy42MDEyMiAxNC41ODQ5SDEuNUMwLjY3MTU3MyAxNC41ODQ5IDAgMTMuOTEzNCAwIDEzLjA4NDlWNy41MDE2Wk01Ljg0OTQ1IDYuOTYwMjdDNS4yNzk1NiA3LjYyMTQzIDQuNDQ5OTcgOC4wMDE2IDMuNTc3MDkgOC4wMDE2SDJWMTIuNTg0OUgzLjYwMTIyQzQuNDMyMDMgMTIuNTg0OSA1LjIyNTY0IDEyLjkyOTUgNS43OTI5NSAxMy41MzY0TDguNSAxNi40MzI4VjMuODg1MjJMNS44NDk0NSA2Ljk2MDI3WiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPHBhdGggZD0iTTEzLjUxNSA3LjE5MTE5QzEzLjM0MjQgNi45NzU1OSAxMy4zMzk5IDYuNjYwNTYgMTMuNTM1MiA2LjQ2NTNMMTQuMjQyMyA1Ljc1ODE5QzE0LjQzNzYgNS41NjI5MyAxNC43NTU4IDUuNTYxNzUgMTQuOTM1NiA1Ljc3MTM2QzE2Ljk5NTkgOC4xNzM2MiAxNi45OTU5IDExLjgyOCAxNC45MzU2IDE0LjIzMDNDMTQuNzU1OCAxNC40Mzk5IDE0LjQzNzYgMTQuNDM4NyAxNC4yNDIzIDE0LjI0MzVMMTMuNTM1MiAxMy41MzY0QzEzLjMzOTkgMTMuMzQxMSAxMy4zNDI0IDEzLjAyNjEgMTMuNTE1IDEyLjgxMDVDMTQuODEzIDExLjE4ODUgMTQuODEzIDguODEzMTIgMTMuNTE1IDcuMTkxMTlaIiBmaWxsPSIjMTYxODIzIiBmaWxsLW9wYWNpdHk9IjAuNiIvPgo8cGF0aCBkPSJNMTYuNzE3MiAxNi43MTgzQzE2LjUyMTkgMTYuNTIzMSAxNi41MjMxIDE2LjIwNzQgMTYuNzA3MiAxNi4wMDE3QzE5LjcyNTcgMTIuNjMgMTkuNzI1NyA3LjM3MTY4IDE2LjcwNzIgNC4wMDAwMUMxNi41MjMxIDMuNzk0MjcgMTYuNTIxOSAzLjQ3ODU4IDE2LjcxNzIgMy4yODMzMkwxNy40MjQzIDIuNTc2MjFDMTcuNjE5NSAyLjM4MDk1IDE3LjkzNyAyLjM4MDIgMTguMTIzMyAyLjU4NDA4QzIxLjkwOTkgNi43MjkyNiAyMS45MDk5IDEzLjI3MjQgMTguMTIzMyAxNy40MTc2QzE3LjkzNyAxNy42MjE1IDE3LjYxOTUgMTcuNjIwNyAxNy40MjQzIDE3LjQyNTVMMTYuNzE3MiAxNi43MTgzWiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPC9zdmc+Cg=="]')
695
+ page.click('img[src="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjEiIGhlaWdodD0iMjAiIHZpZXdCb3g9IjAgMCAyMSAyMCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTAgNy41MDE2QzAgNi42NzMxNyAwLjY3MTU3MyA2LjAwMTYgMS41IDYuMDAxNkgzLjU3NzA5QzMuODY4MDUgNi4wMDE2IDQuMTQ0NTggNS44NzQ4OCA0LjMzNDU1IDUuNjU0NDlMOC43NDI1NSAwLjU0MDUyQzkuMzQ3OCAtMC4xNjE2NjggMTAuNSAwLjI2NjM3NCAxMC41IDEuMTkzNDFWMTguOTY3MkMxMC41IDE5Ljg3NDUgOS4zODg5NCAyMC4zMTI5IDguNzY5NDIgMTkuNjVMNC4zMzE3OSAxNC45MDIxQzQuMTQyNjkgMTQuNjk5OCAzLjg3ODE2IDE0LjU4NDkgMy42MDEyMiAxNC41ODQ5SDEuNUMwLjY3MTU3MyAxNC41ODQ5IDAgMTMuOTEzNCAwIDEzLjA4NDlWNy41MDE2Wk01Ljg0OTQ1IDYuOTYwMjdDNS4yNzk1NiA3LjYyMTQzIDQuNDQ5OTcgOC4wMDE2IDMuNTc3MDkgOC4wMDE2SDJWMTIuNTg0OUgzLjYwMTIyQzQuNDMyMDMgMTIuNTg0OSA1LjIyNTY0IDEyLjkyOTUgNS43OTI5NSAxMy41MzY0TDguNSAxNi40MzI4VjMuODg1MjJMNS44NDk0NSA2Ljk2MDI3WiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPHBhdGggZD0iTTEzLjUxNSA3LjE5MTE5QzEzLjM0MjQgNi45NzU1OSAxMy4zMzk5IDYuNjYwNTYgMTMuNTM1MiA2LjQ2NTNMMTQuMjQyMyA1Ljc1ODE5QzE0LjQzNzYgNS41NjI5MyAxNC43NTU4IDUuNTYxNzUgMTQuOTM1NiA1Ljc3MTM2QzE2Ljk5NTkgOC4xNzM2MiAxNi45OTU5IDExLjgyOCAxNC45MzU2IDE0LjIzMDNDMTQuNzU1OCAxNC40Mzk5IDE0LjQzNzYgMTQuNDM4NyAxNC4yNDIzIDE0LjI0MzVMMTMuNTM1MiAxMy41MzY0QzEzLjMzOTkgMTMuMzQxMSAxMy4zNDI0IDEzLjAyNjEgMTMuNTE1IDEyLjgxMDVDMTQuODEzIDExLjE4ODUgMTQuODEzIDguODEzMTIgMTMuNTE1IDcuMTkxMTlaIiBmaWxsPSIjMTYxODIzIiBmaWxsLW9wYWNpdHk9IjAuNiIvPgo8cGF0aCBkPSJNMTYuNzE3MiAxNi43MTgzQzE2LjUyMTkgMTYuNTIzMSAxNi41MjMxIDE2LjIwNzQgMTYuNzA3MiAxNi4wMDE3QzE5LjcyNTcgMTIuNjMgMTkuNzI1NyA3LjM3MTY4IDE2LjcwNzIgNC4wMDAwMUMxNi41MjMxIDMuNzk0MjcgMTYuNTIxOSAzLjQ3ODU4IDE2LjcxNzIgMy4yODMzMkwxNy40MjQzIDIuNTc2MjFDMTcuNjE5NSAyLjM4MDk1IDE3LjkzNyAyLjM4MDIgMTguMTIzMyAyLjU4NDA4QzIxLjkwOTkgNi43MjkyNiAyMS45MDk5IDEzLjI3MjQgMTguMTIzMyAxNy40MTc2QzE3LjkzNyAxNy42MjE1IDE3LjYxOTUgMTcuNjIwNyAxNy40MjQzIDE3LjQyNTVMMTYuNzE3MiAxNi43MTgzWiIgZmlsbD0iIzE2MTgyMyIgZmlsbC1vcGFjaXR5PSIwLjYiLz4KPC9zdmc+Cg=="]')
696
+ time.sleep(0.5)
697
+ sliders = page.locator("input.scaleInput")
698
+
699
+ if sound_aud_vol == 'background':
700
+ slider1 = sliders.nth(0)
701
+ bounding_box1 = slider1.bounding_box()
702
+ if bounding_box1:
703
+ x1 = bounding_box1["x"] + (bounding_box1["width"] * 0.92)
704
+ y1 = bounding_box1["y"] + bounding_box1["height"] / 2
705
+ page.mouse.click(x1, y1)
706
+
707
+ slider2 = sliders.nth(1)
708
+ bounding_box2 = slider2.bounding_box()
709
+ if bounding_box2:
710
+ x2 = bounding_box2["x"] + (bounding_box2["width"] * 0.097)
711
+ y2 = bounding_box2["y"] + bounding_box2["height"] / 2
712
+ page.mouse.click(x2, y2)
713
+
714
+ if sound_aud_vol == 'main':
715
+ slider1 = sliders.nth(0)
716
+ bounding_box1 = slider1.bounding_box()
717
+ if bounding_box1:
718
+ x1 = bounding_box1["x"] + (bounding_box1["width"] * 0.092)
719
+ y1 = bounding_box1["y"] + bounding_box1["height"] / 2
720
+ page.mouse.click(x1, y1)
721
+ slider2 = sliders.nth(1)
722
+ bounding_box2 = slider2.bounding_box()
723
+ if bounding_box2:
724
+ x2 = bounding_box2["x"] + (bounding_box2["width"] * 0.92)
725
+ y2 = bounding_box2["y"] + bounding_box2["height"] / 2
726
+ page.mouse.click(x2, y2)
727
+ except:
728
+ sys.exit("ERROR ADJUSTING SOUND VOLUME: please try again.")
729
+
730
+ page.wait_for_selector("div.TUXButton-label:has-text('Save edit')")
731
+ page.click("div.TUXButton-label:has-text('Save edit')")
732
+ if suppressprint == False:
733
+ print("Added sound")
734
+
735
+
736
+ page.wait_for_selector('div[data-contents="true"]')
737
+
738
+ if copyrightcheck == True:
739
+ page.click('div.TUXSwitch:has(label.TUXSwitch-label:has-text("Run a copyright check")) input.TUXSwitch-input')
740
+ while copyrightcheck == True:
741
+ time.sleep(0.2)
742
+ if page.locator("span", has_text="No issues detected.").is_visible():
743
+ if suppressprint == False:
744
+ print("Copyright check complete")
745
+ break
746
+ if page.locator("span", has_text="Copyright issues detected.").is_visible():
747
+ sys.exit("COPYRIGHT CHECK FAILED: VIDEO SAVED AS DRAFT, COPYRIGHT AUDIO DETECTED FROM TIKTOK")
748
+
749
+
750
+ try:
751
+ if schedule == None:
752
+ page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Post")', timeout=10000)
753
+ uploaded = False
754
+ checks = 0
755
+ while uploaded == False:
756
+ if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
757
+ time.sleep(0.2)
758
+ break
759
+ time.sleep(0.2)
760
+ checks += 1
761
+ if checks == 25:
762
+ break
763
+ else:
764
+ page.click('button.TUXButton.TUXButton--default.TUXButton--large.TUXButton--primary:has-text("Schedule")', timeout=10000)
765
+ uploaded = False
766
+ checks = 0
767
+ while uploaded == False:
768
+ if page.locator(':has-text("Leaving the page does not interrupt")').nth(0).is_visible():
769
+ time.sleep(0.1)
770
+ break
771
+ time.sleep(0.2)
772
+ checks += 1
773
+ if checks == 25:
774
+ break
775
+ if suppressprint == False:
776
+ print("Done uploading video, NOTE: it may take a minute or two to show on TikTok")
777
+ except:
778
+ time.sleep(2)
779
+ sys.exit("POSSIBLE ERROR UPLOADING: Cannot confirm if uploaded successfully, Please check account in a minute or two to confirm.")
780
+ time.sleep(1)
781
+
782
+ page.close()
783
+
784
+ return "Completed"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: tiktokautouploader
3
- Version: 2.98
3
+ Version: 3.3
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>
@@ -17,7 +17,6 @@ Requires-Dist: inference>=0.18.1
17
17
  Requires-Dist: pillow>=8.0.0
18
18
  Requires-Dist: playwright>=1.0.0
19
19
  Requires-Dist: requests>=2.0.0
20
- Requires-Dist: scikit-learn>=0.24.0
21
20
  Description-Content-Type: text/markdown
22
21
 
23
22
  <div align="center">
@@ -29,9 +28,8 @@ Description-Content-Type: text/markdown
29
28
 
30
29
  [![PyPI version](https://img.shields.io/pypi/v/tiktokautouploader.svg)](https://pypi.org/project/tiktokautouploader/) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
31
30
 
32
-
33
31
  <p align="center">
34
- <img src="READMEimage/READMEvid.gif" alt="" width="900"/>
32
+ <img src="READMEimage/READMEGIF.gif" alt="" width="900"/>
35
33
  </p>
36
34
 
37
35
  ## 🚀 Features
@@ -41,8 +39,10 @@ Description-Content-Type: text/markdown
41
39
  - **🗓 Schedule Uploads:** Upload videos at specific times or upto 10 days in advance with our scheduling feature.
42
40
  - **🔍 Copyright Check:** Ensure your video is safe from copyright claims before uploading.
43
41
  - **🏷 Add Working Hashtags:** Increase your reach by adding effective hashtags that actually work.
44
- - **⏰ Cutdown on upload time:** Upload to TikTok with way less hassle and much more speed using our library
42
+ - **⏰ Cutdown on upload time:** Upload to TikTok with way less hassle and much more speed using our library.
43
+ - **📝 Upload to different accounts:** Stay organized and on top of multiple different accounts with our multi-account functionality.
45
44
 
45
+ ⭐️ If you like this project please feel free to star it, Thank you.
46
46
 
47
47
  ## 📦 Installation
48
48
 
@@ -52,7 +52,7 @@ Description-Content-Type: text/markdown
52
52
  pip install tiktokautouploader
53
53
  ```
54
54
 
55
- **NOTE:** IF YOU HAVE INSTALLED BEFORE, PLEASE MAKE SURE YOU HAVE LATEST VERSION INSTALLED OR ELSE YOU MIGHT FACE BUGS
55
+ **NOTE:** IF YOU HAVE INSTALLED BEFORE, PLEASE MAKE SURE YOU UPGRADE TO THE LATEST VERSION.
56
56
 
57
57
  ---
58
58
 
@@ -77,7 +77,7 @@ pip install tiktokautouploader
77
77
  ## 📝 Quick-Start
78
78
 
79
79
  **NOTE:** It is highly recommended you read DOCUMENTATION.md before using the library.
80
- 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.
80
+ 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.
81
81
 
82
82
  ## Upload with hashtags
83
83
 
@@ -86,16 +86,17 @@ from tiktokautouploader import upload_tiktok
86
86
 
87
87
  video_path = 'path/to/your/video.mp4'
88
88
  description = 'Check out my latest TikTok video!'
89
+ accountname = 'mytiktokaccount'
89
90
  hashtags = ['#fun', '#viral']
90
91
 
91
- upload_tiktok(video=video_path, description=description, hashtags=hashtags)
92
+ upload_tiktok(video=video_path, description=description, accountname=accountname, hashtags=hashtags)
92
93
 
93
94
  ```
94
95
 
95
96
  ### Upload with TikTok Sound
96
97
 
97
98
  ```python
98
- upload_tiktok(video=video_path, description=description, sound_name='trending_sound', sound_aud_vol='main')
99
+ upload_tiktok(video=video_path, description=description, accountname=accountname, sound_name='trending_sound', sound_aud_vol='main')
99
100
  ```
100
101
 
101
102
  PLEASE READ DOCUMENTATION FOR MORE INFO.
@@ -103,7 +104,7 @@ PLEASE READ DOCUMENTATION FOR MORE INFO.
103
104
  ### Schedule an Upload
104
105
 
105
106
  ```python
106
- upload_tiktok(video=video_path, description=description, schedule='03:10', day=11)
107
+ upload_tiktok(video=video_path, description=description, accountname=accountname, schedule='03:10', day=11)
107
108
  ```
108
109
 
109
110
  PLEASE READ DOCUMENTATION FOR MORE INFO
@@ -111,16 +112,17 @@ PLEASE READ DOCUMENTATION FOR MORE INFO
111
112
  ### Perform Copyright Check Before Uploading
112
113
 
113
114
  ```python
114
- upload_tiktok(video=video_path, description=description, hashtags=hashtags, copyrightcheck=True)
115
+ upload_tiktok(video=video_path, description=description, accountname=accountname, hashtags=hashtags, copyrightcheck=True)
115
116
  ```
116
117
 
117
118
  ## 🎯 Why Choose `autotiktokuploader`?
118
119
 
119
120
  - **No more captchas:** Fully automated uploads without interruptions, If captchas do show up, no worries, they will be solved. (read documentation for more info)
120
- - **Maximize your reach:** Add popular sounds and effective hashtags that work to boost visibility.
121
+ - **Maximize your reach:** Add popular sounds and effective hashtags that work to boost visibility and go viral!
121
122
  - **Stay compliant:** Built-in copyright checks to avoid unforeseen takedowns.
122
- - **Convenient scheduling:** Post at the right time, even when you're away.
123
+ - **Convenient scheduling:** Post at the right time, even when you're away!
123
124
  - **Much faster than manually uploading:** Drastically reduce the time you need to upload videos, just click one button and be done much quicker!
125
+ - **Upload to different account:** Stay on top of all your TikTok accounts with our multi-account functionality!
124
126
 
125
127
  ## 🛠 Dependencies
126
128
 
@@ -141,4 +143,10 @@ Created by **Haziq**. Feel free to reach out at [haziqmk123@gmail.com](mailto:ha
141
143
  ## 📄 License
142
144
 
143
145
  This project is licensed under the MIT License. See the [LICENSE](LICENSE.md) file for details.
144
- ```
146
+
147
+ ## 📮 Related Projects
148
+
149
+ If you liked this project please check out my use case showcase project that generates TikToks and uploads them using 'tiktokautouploader'
150
+
151
+ [TikTokGenerator](https://github.com/haziq-exe/TikTokGenerator)
152
+
@@ -0,0 +1,7 @@
1
+ tiktokautouploader/__init__.py,sha256=u7OWCK_u68ST8dfrkSF4Yw44CJOzV9NXI6ASRuoDfmE,64
2
+ tiktokautouploader/function.py,sha256=Z3Ic2fRzmMMVlvhovzGO0RcZGgkllk_9XbjvjUpjvHw,44657
3
+ tiktokautouploader/Js_assets/login.js,sha256=SLhtPYo8ZfTRUnbR7Xqp084lSuAOqIWUxi75FlFH3vs,966
4
+ tiktokautouploader-3.3.dist-info/METADATA,sha256=U7Tbvg0Gm64NiCMlKRMXRn3nJTuBRso-VLCQykpDIes,6125
5
+ tiktokautouploader-3.3.dist-info/WHEEL,sha256=fl6v0VwpzfGBVsGtkAkhILUlJxROXbA3HvRL6Fe3140,105
6
+ tiktokautouploader-3.3.dist-info/licenses/LICENSE.md,sha256=hYds_VJIpnS5gC73WhuWk2IY_e9BWjuEJthQCb9ThyU,1073
7
+ tiktokautouploader-3.3.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- tiktokautouploader/__init__.py,sha256=u7OWCK_u68ST8dfrkSF4Yw44CJOzV9NXI6ASRuoDfmE,64
2
- tiktokautouploader/function.py,sha256=wUI4r8dPIj6eSyi2WvBFJHb3zYyNAPonw_xrrMtJvBQ,35203
3
- tiktokautouploader/Js_assets/login.js,sha256=SLhtPYo8ZfTRUnbR7Xqp084lSuAOqIWUxi75FlFH3vs,966
4
- tiktokautouploader-2.98.dist-info/METADATA,sha256=NXjc7EasXewxxIrnTJSb295_-UD9Q4-AcA5aKy5Jt98,5464
5
- tiktokautouploader-2.98.dist-info/WHEEL,sha256=fl6v0VwpzfGBVsGtkAkhILUlJxROXbA3HvRL6Fe3140,105
6
- tiktokautouploader-2.98.dist-info/licenses/LICENSE.md,sha256=hYds_VJIpnS5gC73WhuWk2IY_e9BWjuEJthQCb9ThyU,1073
7
- tiktokautouploader-2.98.dist-info/RECORD,,