Skip to content

Commit

Permalink
V0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
wkaisertexas committed Feb 18, 2023
1 parent 66da618 commit 4455b69
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 26 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Customized items
test.py

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
38 changes: 31 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
# TikTok Uploader
# ⬆️ TikTok Uploader

![Downloads](https://img.shields.io/github/downloads/wkaisertexas/tiktok-uploader/total)

A selenium-based uploader for TikTok Videos

## Usage

While Tik Tok is pretty good about blocking bots (giving "too many requests" with FireFox's default installation"), simply copying your session tokens is enough to bypass this restriction and be able to upload your videos.

```bash
$ tiktok_uploader -v video.mp4 -d "this is my description" -c cookies.txt
```

```python
upload_video('video.mp4', description='this is my description', cookies='cookies.txt') # single video

# Multiple Videos
videos = [
{'path': 'video.mp4', 'description': 'this is my description'},
{'path': 'video2.mp4', 'description': 'this is also my description'}
]
auth = AuthBackend(cookies='cookies.txt')
upload_videos(videos=videos, auth=auth)
```
### Uploading videos

This library revolves around the 'upload_video' function which takes in a list of videos which have **filenames** and **descriptions** and are passed as follows:
Expand Down Expand Up @@ -33,7 +51,9 @@ Finally, pass the saved file path to `upload_videos`.
upload_videos(cookies='cookies.txt')
```

> Optionally, if you would like to pass your own cookies you may do as an array of dictionaries with keys `name`, `value`, `domain`, `path` and `expiry` though there really is no need
> Optionally, if you would like to pass your own cookies you may do as an array of dictionaries with keys `name`, `value`, `domain`, `path` and `expiry`
> The login script does have a `login_accounts` function, but this gets detected by the
#### Login-based Authentication

Expand All @@ -42,9 +62,7 @@ upload_videos(cookies='cookies.txt')
To use password authentication, pass your **username** and **password** as keyword arguments to `upload_videos`.

```python
upload_videos(username='mytiktokusername', password='*******')
# or
upload_videos(login_info=('mytiktokusername', '*********')
upload_video(username='mytiktokusername', password='*******')
```

> As a side note, try to avoid keeping passwords as values in your code. You can read more about why [here](https://medium.com/twodigits/keep-passwords-out-of-source-code-why-and-how-e84f9004815a).
Expand All @@ -68,10 +86,16 @@ options = Options()

options.add_argument('start-maximized')

upload_videos(browser_agent=options)
upload_videos(options=options)
```

> Note: Options are Browser specific
> Note: Make sure to use the right selenium options for your browser
### Headless Browsers

**Headless browsers do not work at this time**

> If more experienced in Webscraping, I would really appreciate helping make this work. [undetected-chromedriver](https://github.com/ultrafunkamsterdam/undetected-chromedriver) was already tried and did not work
## Installation

Expand Down
8 changes: 4 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
[project]
name = "tiktok_uploader"
version = "0.0.1"
version = "0.1.0"
authors = [
{ name="William Kaiser", email="[email protected]" },
]
description = "An automatic TikTok video uploader w/ CLI"
description = "An automatic TikTok video uploader w/ CLI. Uses cookies from your browser to manage authentication and upload your videos automatically."
readme = "README.md"
requires-python = ">=3.11"
keywords = [
Expand Down Expand Up @@ -33,8 +33,8 @@ test = [
"pytest",
]

# [tool.hatch.envs.test.matrix]
# python = ["38", "39"]
[tool.hatch.envs.test.matrix]
python = ["38", "39"]

[project.scripts]
tiktok_uploader = "tiktok_uploader.cli:cli"
Expand Down
2 changes: 1 addition & 1 deletion src/tiktok_uploader/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ def main():
"""
Entry point for TikTok-Uploader, makes a call to CLI
"""
cli.main()
cli.cli()

if __name__ == '__main__':
main()
8 changes: 4 additions & 4 deletions src/tiktok_uploader/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@
class AuthBackend:
username: str
password: str
cookies: dict
cookies: list

def __init__(self, username=None, password=None, cookies=[], cookies_path=None):
def __init__(self, username: str = '', password: str = '', cookies=[], cookies_path=None):
"""
Creates the authenticaiton backend
Expand Down Expand Up @@ -84,15 +84,15 @@ def get_cookies(self, path: str) -> dict:
]


def login_accounts(driver=None, accounts=[(None, None)]) -> list:
def login_accounts(driver=None, accounts=[(None, None)], *args, **kwargs) -> list:
"""
Authenticates the accounts using the browser backend and saves the required credentials
Keyword arguments:
- driver -> the webdriver to use
- accounts -> a list of tuples of the form (username, password)
"""
driver = driver or get_browser(headless=False)
driver = driver or get_browser(headless=False, *args, **kwargs)

cookies = {}
for account in accounts:
Expand Down
21 changes: 14 additions & 7 deletions src/tiktok_uploader/browsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,15 @@

from tiktok_uploader import config


def get_browser(name: str = 'chrome', *args, **kwargs) -> webdriver:
def get_browser(name: str = 'chrome', options=None, *args, **kwargs) -> webdriver:
"""
Gets a browser based on the name with the ability to pass in additional arguments
"""
# get the web driver for the browser
driver_to_use = get_driver(name=name)
driver_to_use = get_driver(name=name, *args, **kwargs)

# gets the options for the browser
options = get_default_options(name=name, *args, **kwargs)
options = options or get_default_options(name=name, *args, **kwargs)

# combines them together into a completed driver
service = get_service(name=name)
Expand All @@ -45,7 +44,7 @@ def get_browser(name: str = 'chrome', *args, **kwargs) -> webdriver:
return driver


def get_driver(name: str = 'chrome') -> webdriver:
def get_driver(name: str = 'chrome', *args, **kwargs) -> webdriver:
"""
Gets the web driver function for the browser
"""
Expand Down Expand Up @@ -96,11 +95,19 @@ def get_default_options(name: str, *args, **kwargs):
raise Exception(f'{name} is not a supported browser')


def chrome_defaults(headless: bool = False, *args, **kwargs) -> ChromeOptions:
def chrome_defaults(headless: bool = False, undetectable=False, *args, **kwargs) -> ChromeOptions:
"""
Creates Chrome with Options
"""
options = ChromeOptions()

if undetectable:
options = uc.ChromeOptions()
if headless:
options.headless = True
options.add_argument( '--headless' )
return options # TODO: Maybe customize the undetectable chromedriver
else:
options = ChromeOptions()

# default options

Expand Down
2 changes: 1 addition & 1 deletion src/tiktok_uploader/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def get_auth_args():

return parser.parse_args()

def validate_auth_args(args: dict):
def validate_auth_args(args):
"""
Preforms validation on each input given
"""
Expand Down
4 changes: 4 additions & 0 deletions src/tiktok_uploader/upload.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,12 +91,16 @@ def upload_videos(videos: list = None, auth: AuthBackend = None, browser='chrome
print(e)
if i == n-1: # adds if the last retry
failed.append(video)

if on_complete: # calls the user-specified on-complete function
on_complete(video)

if config['quit_on_end']:
driver.quit()

return failed


def complete_upload_form(driver, path: str, description: str, *args, **kwargs) -> None:
"""
Actually uploades each video
Expand Down
4 changes: 2 additions & 2 deletions test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

if __name__ == '__main__':
# Uploads a video to TikTok
# upload_video('../../Desktop/video.mp4', description='this is a story about why I don', cookies='../../Desktop/cookies.txt', headless=True)
upload_video('../../Desktop/video.mp4', description='this is a story about why I don', cookies='../../Desktop/cookies.txt', headless=True)

# tests cookies for accounts -> Works except I get too many requests error (really sad)
# tiktok_uploader.auth.login_accounts(accounts=[('[email protected]', 'asdfse12323dfsd!')])
system('tiktok_uploader -v ../../Desktop/video.mp4 -d "this is a story about why I don\'t like tiktok" -c ../../Desktop/cookies.txt')
# system('tiktok_uploader -v ../../Desktop/video.mp4 -d "this is a story about why I don\'t like tiktok" -c ../../Desktop/cookies.txt')

0 comments on commit 4455b69

Please sign in to comment.