From b9b1a8f93d3d1d8c26a34085f4d8a336652df535 Mon Sep 17 00:00:00 2001
From: yihong0618 <zouzou0208@gmail.com>
Date: Wed, 17 Jul 2024 19:26:12 +0800
Subject: [PATCH] feat: kling

Signed-off-by: yihong0618 <zouzou0208@gmail.com>
---
 handlers/kling.py | 145 ++++++++++++++++++++++++++++++++++++++++++++++
 pdm.lock          |  26 ++++++++-
 pyproject.toml    |   1 +
 requirements.txt  |   2 +
 4 files changed, 173 insertions(+), 1 deletion(-)
 create mode 100644 handlers/kling.py

diff --git a/handlers/kling.py b/handlers/kling.py
new file mode 100644
index 0000000..43e84be
--- /dev/null
+++ b/handlers/kling.py
@@ -0,0 +1,145 @@
+import re
+from telebot import TeleBot
+from telebot.types import Message
+from telebot.types import InputMediaPhoto
+from os import environ
+from expiringdict import ExpiringDict
+from kling import ImageGen, VideoGen
+import requests
+
+from . import *
+
+KLING_COOKIE = environ.get("KLING_COOKIE")
+pngs_link_dict = ExpiringDict(max_len=100, max_age_seconds=60 * 10)
+
+
+def kling_handler(message: Message, bot: TeleBot):
+    """kling: /kling <address>"""
+    bot.reply_to(
+        message,
+        f"Generating pretty kling image may take some time please wait",
+    )
+    m = message.text.strip()
+    prompt = m.strip()
+    links = None
+    try:
+        i = ImageGen(KLING_COOKIE)
+        links = i.get_images(prompt)
+        # set the dict
+        try:
+            pngs_link_dict[str(message.from_user.id)] = links
+        except Exception as e:
+            print(str(e))
+    except Exception as e:
+        print(str(e))
+        bot.reply_to(message, "kling error maybe block the prompt")
+        return
+    photos_list = [InputMediaPhoto(i) for i in links]
+    bot.send_media_group(
+        message.chat.id,
+        photos_list,
+        reply_to_message_id=message.message_id,
+        disable_notification=True,
+    )
+
+
+def kling_pro_handler(message: Message, bot: TeleBot):
+    """kling: /kling <address>"""
+    bot.reply_to(
+        message,
+        f"Generating pretty kling video may take a long time about 2mins to 5mins please wait",
+    )
+    m = message.text.strip()
+    prompt = m.strip()
+    # drop all the spaces
+    prompt = prompt.replace(" ", "")
+    # find `图{number}` in prompt
+    number = re.findall(r"图\d+", prompt)
+    number = number[0] if number else None
+    if number:
+        number = int(number.replace("图", ""))
+    v = VideoGen(KLING_COOKIE)
+    video_links = None
+    image_url = None
+    if number and number <= 9 and pngs_link_dict.get(str(message.from_user.id)):
+        if number - 1 <= len(pngs_link_dict.get(str(message.from_user.id))):
+            image_url = pngs_link_dict.get(str(message.from_user.id))[number - 1]
+            print(image_url)
+    try:
+        video_links = v.get_video(prompt, image_url=image_url)
+    except Exception as e:
+        print(str(e))
+        bot.reply_to(message, "kling error maybe block the prompt")
+        return
+    if not video_links:
+        bot.reply_to(message, "video not generate")
+        return
+    response = requests.get(video_links[0])
+    if response.status_code != 200:
+        bot.reply_to(message, "could not fetch the video")
+    # save response to file
+    with open("kling.mp4", "wb") as output_file:
+        output_file.write(response.content)
+    bot.send_video(
+        message.chat.id,
+        open("kling.mp4", "rb"),
+        caption=prompt,
+        reply_to_message_id=message.message_id,
+    )
+
+
+def kling_photo_handler(message: Message, bot: TeleBot) -> None:
+    s = message.caption
+    prompt = s.strip()
+    # show something, make it more responsible
+    # get the high quaility picture.
+    max_size_photo = max(message.photo, key=lambda p: p.file_size)
+    file_path = bot.get_file(max_size_photo.file_id).file_path
+    downloaded_file = bot.download_file(file_path)
+    bot.reply_to(
+        message,
+        f"Generating pretty kling image using your photo may take some time please wait",
+    )
+    with open("kling.jpg", "wb") as temp_file:
+        temp_file.write(downloaded_file)
+    i = ImageGen(KLING_COOKIE)
+    links = None
+    try:
+        links = i.get_images(prompt, "kling.jpg")
+        # set the dict
+        try:
+            pngs_link_dict[str(message.from_user.id)] = links
+        except Exception as e:
+            print(str(e))
+    except Exception as e:
+        print(str(e))
+        bot.reply_to(message, "kling error maybe block the prompt")
+        return
+    photos_list = [InputMediaPhoto(i) for i in links]
+    bot.send_media_group(
+        message.chat.id,
+        photos_list,
+        reply_to_message_id=message.message_id,
+        disable_notification=True,
+    )
+
+
+if KLING_COOKIE:
+
+    def register(bot: TeleBot) -> None:
+        bot.register_message_handler(kling_handler, commands=["kling"], pass_bot=True)
+        bot.register_message_handler(kling_handler, regexp="^kling:", pass_bot=True)
+        # kling pro means video
+        bot.register_message_handler(
+            kling_pro_handler, commands=["kling_pro"], pass_bot=True
+        )
+        bot.register_message_handler(
+            kling_pro_handler, regexp="^kling_pro:", pass_bot=True
+        )
+        bot.register_message_handler(
+            kling_photo_handler,
+            content_types=["photo"],
+            func=lambda m: m.caption
+            and m.caption.startswith(("kling:", "/kling", "kling:", "/kling")),
+            pass_bot=True,
+        )
diff --git a/pdm.lock b/pdm.lock
index 13020e1..028eaa1 100644
--- a/pdm.lock
+++ b/pdm.lock
@@ -5,7 +5,7 @@
 groups = ["default"]
 strategy = ["cross_platform", "inherit_metadata"]
 lock_version = "4.4.1"
-content_hash = "sha256:d025c0ed6e8de18327d2d51e25f8888abf6941e38a46058c3cae5cfb10a192f9"
+content_hash = "sha256:aba181a6c13ad9597f83d583db757ee075dcb1a92f9849f7e8b7cfaea8202b07"
 
 [[package]]
 name = "aiohttp"
@@ -666,6 +666,16 @@ files = [
     {file = "expiringdict-1.2.2.tar.gz", hash = "sha256:300fb92a7e98f15b05cf9a856c1415b3bc4f2e132be07daa326da6414c23ee09"},
 ]
 
+[[package]]
+name = "fake-useragent"
+version = "1.5.1"
+summary = "Up-to-date simple useragent faker with real world database"
+groups = ["default"]
+files = [
+    {file = "fake-useragent-1.5.1.tar.gz", hash = "sha256:6387269f5a2196b5ba7ed8935852f75486845a1c95c50e72460e6a8e762f5c49"},
+    {file = "fake_useragent-1.5.1-py3-none-any.whl", hash = "sha256:57415096557c8a4e23b62a375c21c55af5fd4ba30549227f562d2c4f5b60e3b3"},
+]
+
 [[package]]
 name = "fastavro"
 version = "1.9.4"
@@ -1308,6 +1318,20 @@ files = [
     {file = "kiwisolver-1.4.5.tar.gz", hash = "sha256:e57e563a57fb22a142da34f38acc2fc1a5c864bc29ca1517a88abc963e60d6ec"},
 ]
 
+[[package]]
+name = "kling-creator"
+version = "0.0.3"
+summary = "High quality video generation by https://klingai.kuaishou.com/. Reverse engineered API."
+groups = ["default"]
+dependencies = [
+    "fake-useragent",
+    "requests",
+]
+files = [
+    {file = "kling_creator-0.0.3-py3-none-any.whl", hash = "sha256:09dc91427b9c77bdf9db4b133b59308ee34e365631eb5891854c05c9fb0acae6"},
+    {file = "kling_creator-0.0.3.tar.gz", hash = "sha256:2325d2afca58d5c6e72dd74bf2e322a56b484c3a65d56473b52ba8d93b9102b9"},
+]
+
 [[package]]
 name = "markdown"
 version = "3.6"
diff --git a/pyproject.toml b/pyproject.toml
index e5ef0cc..7bd152c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -22,5 +22,6 @@ dependencies = [
     "beautifulsoup4>=4.12.3",
     "Markdown>=3.6",
     "cohere>=5.5.8",
+    "kling-creator>=0.0.3",
 ]
 requires-python = ">=3.10"
diff --git a/requirements.txt b/requirements.txt
index 053e031..621c9c6 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -38,6 +38,7 @@ encodec==0.1.1
 eval-type-backport==0.2.0
 exceptiongroup==1.2.1; python_version < "3.11"
 expiringdict==1.2.2
+fake-useragent==1.5.1
 fastavro==1.9.4
 filelock==3.14.0
 fiona==1.9.6
@@ -68,6 +69,7 @@ intel-openmp==2021.4.0; platform_system == "Windows"
 jinja2==3.1.4
 jmespath==1.0.1
 kiwisolver==1.4.5
+kling-creator==0.0.3
 markdown==3.6
 markdown-it-py==3.0.0
 markupsafe==2.1.5