Add UploadEngine and its dependencies

This commit is contained in:
2024-02-22 15:13:45 +01:00
parent 7323b4aad9
commit f83a18fecb
5 changed files with 216 additions and 2 deletions

View File

@@ -0,0 +1,12 @@
from abc import abstractmethod
from .. import BaseEngine
class BaseUploadEngine(BaseEngine):
def __init__(self, **kwargs) -> None:
...
@abstractmethod
def upload(self):
...

View File

@@ -0,0 +1,75 @@
import gradio as gr
from tiktok_uploader.upload import upload_video
from .BaseUploadEngine import BaseUploadEngine
class TikTokUploadEngine(BaseUploadEngine):
name = "TikTokUpload"
description = "Upload to TikTok"
num_options = 1
def __init__(self, options) -> None:
self.hashtags = options[0]
super().__init__()
def upload(self):
cookies = self.get_setting(type="cookies")["cookies"]
if cookies == None:
gr.Warning(
"Skipping upload to TikTok because no cookies were provided. Please provide cookies in the settings."
)
return
title: str = self.ctx.title
description: str = self.ctx.description
hastags = self.hashtags.strip().split(" ")
# extract any hashtags from the description / title and remove them from the description
for word in title.split():
if word.startswith("#"):
hastags.append(word)
title = title.replace(word, "")
for word in description.split():
if word.startswith("#"):
hastags.append(word)
description = description.replace(word, "")
title = title.strip()
description = description.strip()
hastags_str = " ".join(hastags) + " " if hastags else ""
failed = upload_video(
filename=self.ctx.get_file_path("final.mp4"),
description=f"{title} {description} {hastags_str}",
cookies_str=cookies,
browser="firefox",
)
for _ in failed:
gr.Error(f"Failed to upload to TikTok")
@classmethod
def get_options(cls):
hashtags = gr.Textbox(label="hashtags", type="text", value="#fyp #foryou")
return [hashtags]
@classmethod
def get_settings(cls):
current_settings = cls.get_setting(type="cookies") or {"cookies": ""}
gr.Markdown(
"Input your TikTok session cookies. You can get them as shown [here](https://github.com/wkaisertexas/tiktok-uploader?tab=readme-ov-file#authentication)."
)
cookies_input = gr.Textbox(
lines=20,
max_lines=50,
label="cookies",
type="text",
value=current_settings["cookies"],
)
cookies_save_btn = gr.Button("Save")
def save(cookies: str):
cls.store_setting(type="cookies", data={"cookies": cookies})
gr.Info("Cookies saved successfully")
cookies_save_btn.click(save, inputs=[cookies_input])

View File

@@ -0,0 +1,115 @@
import gradio as gr
import orjson
from google_auth_oauthlib.flow import InstalledAppFlow
from . import BaseUploadEngine
from ...utils import youtube_uploading
class YouTubeUploadEngine(BaseUploadEngine):
name = "YouTube"
description = "Upload videos to YouTube"
num_options = 2
def __init__(self, options: list):
self.oauth_name = options[0]
self.oauth = self.retrieve_setting(type="oauth_credentials")[self.oauth_name]
self.credentials = self.retrieve_setting(type="youtube_client_secrets")[self.oauth["client_secret"]]
self.hashtags = options[1]
@classmethod
def __oauth(cls, credentials):
flow = InstalledAppFlow.from_client_config(
credentials, scopes=["https://www.googleapis.com/auth/youtube.upload"]
)
user_credentials = flow.run_local_server(
success_message="Heyy, yippie, you're authenticated ! You can close this window now !",
authorization_prompt_message="Please authorize this app to upload videos on your YouTube account !",
)
result = user_credentials.to_json()
if isinstance(result, str):
result = orjson.loads(result)
return result
def upload(self):
options = {
"file": self.ctx.get_file_path("final.mp4"),
"title": self.ctx.title + " | " + self.hashtags,
"description": self.ctx.description,
"privacyStatus": "private",
"category": 28,
}
try:
youtube_uploading.upload(self.oauth["credentials"], options)
except Exception as e:
#this means we need to re-authenticate likely
# use self.__oauth to re-authenticate
new_oauth = self.__oauth(self.credentials)
#also update the credentials in the settings
current_oauths = self.retrieve_setting(type="oauth_credentials") or {}
current_oauths[self.oauth_name] = {
"client_secret": self.oauth["client_secret"],
"credentials": new_oauth
}
self.store_setting(
type="oauth_credentials",
data=current_oauths,
)
self.oauth = current_oauths[self.oauth_name]
youtube_uploading.upload(self.oauth["credentials"], options)
@classmethod
def get_options(cls):
choices = cls.retrieve_setting(type="oauth_credentials") or {}
choices = list(choices.keys())
return [
gr.Dropdown(
choices=choices, label="Choose Channel", value=choices[0] if choices else "No channels available !"
),
gr.Textbox(label="Hashtags", value="#shorts", max_lines=1),
]
@classmethod
def get_settings(cls):
with gr.Row():
with gr.Column() as ytb_secret:
clien_secret_name = gr.Textbox(label="Name", max_lines=1)
client_secret_file = gr.File(
label="Client Secret File", file_types=["json"], type="binary"
)
submit_button = gr.Button("Save")
def save(binary, clien_secret_name):
current_client_secrets = cls.retrieve_setting(type="youtube_client_secrets") or {}
client_secret_json = orjson.loads(binary)
current_client_secrets[clien_secret_name] = client_secret_json
cls.store_setting(
type="youtube_client_secrets",
data=current_client_secrets,
)
gr.Info(f"{clien_secret_name} saved successfully !")
submit_button.click(save, inputs=[client_secret_file, clien_secret_name])
with gr.Column() as ytb_oauth:
possible_client_secrets = cls.retrieve_setting(type="youtube_client_secrets") or {}
possible_client_secrets = list(possible_client_secrets.keys())
choosen_client_secret = gr.Dropdown(label="Login secret", choices=possible_client_secrets)
name = gr.Textbox(label="Name", max_lines=1)
login_button = gr.Button("Login", variant="primary")
def login(choosen_client_secret, name):
choosen_secret_data = cls.retrieve_setting(type="youtube_client_secrets")[choosen_client_secret]
new_oauth_entry = cls.__oauth(choosen_secret_data)
current_oauths = cls.retrieve_setting(type="oauth_credentials") or {}
current_oauths[name] = {
"client_secret": choosen_client_secret,
"credentials": new_oauth_entry
}
cls.store_setting(
type="oauth_credentials",
data=current_oauths,
)
gr.Info(f"{name} saved successfully !")
login_button.click(login, inputs=[choosen_client_secret, name])

View File

@@ -0,0 +1,3 @@
from .BaseUploadEngine import BaseUploadEngine
from .TikTokUploadEngine import TikTokUploadEngine
from .YouTubeUploadEngine import YouTubeUploadEngine

View File

@@ -9,6 +9,7 @@ from . import AssetsEngine
from . import SettingsEngine
from . import BackgroundEngine
from . import MetadataEngine
from . import UploadEngine
class EngineDict(TypedDict):
@@ -38,7 +39,7 @@ ENGINES: dict[str, EngineDict] = {
"multiple": False,
},
"TTSEngine": {
"classes": [TTSEngine.CoquiTTSEngine, TTSEngine.ElevenLabsTTSEngine],
"classes": [TTSEngine.CoquiTTSEngine],
"multiple": False,
},
"CaptioningEngine": {
@@ -46,7 +47,11 @@ ENGINES: dict[str, EngineDict] = {
"multiple": False,
},
"AssetsEngine": {
"classes": [AssetsEngine.DallEAssetsEngine, NoneEngine],
"classes": [
AssetsEngine.DallEAssetsEngine,
AssetsEngine.GoogleAssetsEngine,
NoneEngine,
],
"multiple": True,
},
"BackgroundEngine": {
@@ -57,4 +62,8 @@ ENGINES: dict[str, EngineDict] = {
"classes": [MetadataEngine.ShortsMetadataEngine],
"multiple": False,
},
"UploadEngine": {
"classes": [UploadEngine.TikTokUploadEngine, UploadEngine.YouTubeUploadEngine, NoneEngine],
"multiple": True,
},
}