sticker-convert 2.8.12__py3-none-any.whl → 2.17.0.0__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.
Files changed (124) hide show
  1. sticker_convert/__main__.py +24 -24
  2. sticker_convert/auth/__init__.py +0 -0
  3. sticker_convert/auth/auth_base.py +19 -0
  4. sticker_convert/auth/auth_discord.py +149 -0
  5. sticker_convert/{utils/auth/get_kakao_auth.py → auth/auth_kakao_android_login.py} +331 -300
  6. sticker_convert/auth/auth_kakao_desktop_login.py +327 -0
  7. sticker_convert/auth/auth_kakao_desktop_memdump.py +281 -0
  8. sticker_convert/{utils/auth/get_line_auth.py → auth/auth_line.py} +98 -80
  9. sticker_convert/auth/auth_signal.py +139 -0
  10. sticker_convert/auth/auth_telethon.py +161 -0
  11. sticker_convert/auth/auth_viber.py +250 -0
  12. sticker_convert/auth/telegram_api.py +736 -0
  13. sticker_convert/cli.py +623 -509
  14. sticker_convert/converter.py +1093 -962
  15. sticker_convert/definitions.py +11 -0
  16. sticker_convert/downloaders/download_band.py +111 -0
  17. sticker_convert/downloaders/download_base.py +171 -130
  18. sticker_convert/downloaders/download_discord.py +92 -0
  19. sticker_convert/downloaders/download_kakao.py +417 -255
  20. sticker_convert/downloaders/download_line.py +484 -472
  21. sticker_convert/downloaders/download_ogq.py +80 -0
  22. sticker_convert/downloaders/download_signal.py +108 -92
  23. sticker_convert/downloaders/download_telegram.py +56 -130
  24. sticker_convert/downloaders/download_viber.py +121 -95
  25. sticker_convert/gui.py +788 -795
  26. sticker_convert/gui_components/frames/comp_frame.py +180 -165
  27. sticker_convert/gui_components/frames/config_frame.py +156 -113
  28. sticker_convert/gui_components/frames/control_frame.py +32 -30
  29. sticker_convert/gui_components/frames/cred_frame.py +232 -162
  30. sticker_convert/gui_components/frames/input_frame.py +139 -137
  31. sticker_convert/gui_components/frames/output_frame.py +112 -110
  32. sticker_convert/gui_components/frames/right_clicker.py +25 -23
  33. sticker_convert/gui_components/windows/advanced_compression_window.py +757 -715
  34. sticker_convert/gui_components/windows/base_window.py +7 -2
  35. sticker_convert/gui_components/windows/discord_get_auth_window.py +79 -0
  36. sticker_convert/gui_components/windows/kakao_get_auth_window.py +511 -186
  37. sticker_convert/gui_components/windows/line_get_auth_window.py +94 -102
  38. sticker_convert/gui_components/windows/signal_get_auth_window.py +84 -135
  39. sticker_convert/gui_components/windows/viber_get_auth_window.py +168 -0
  40. sticker_convert/ios-message-stickers-template/.github/FUNDING.yml +3 -3
  41. sticker_convert/ios-message-stickers-template/.gitignore +0 -0
  42. sticker_convert/ios-message-stickers-template/README.md +10 -10
  43. sticker_convert/ios-message-stickers-template/stickers/Info.plist +43 -43
  44. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Info.plist +31 -31
  45. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Contents.json +6 -6
  46. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Contents.json +20 -20
  47. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 1.sticker/Contents.json +9 -9
  48. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 1.sticker/Sticker 1.png +0 -0
  49. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 2.sticker/Contents.json +9 -9
  50. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 2.sticker/Sticker 2.png +0 -0
  51. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 3.sticker/Contents.json +9 -9
  52. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/Sticker Pack.stickerpack/Sticker 3.sticker/Sticker 3.png +0 -0
  53. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/App-Store-1024x1024pt.png +0 -0
  54. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Contents.json +91 -91
  55. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-App-Store-1024x768pt.png +0 -0
  56. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPad-67x50pt@2x.png +0 -0
  57. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPad-Pro-74x55pt@2x.png +0 -0
  58. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPhone-60x45pt@2x.png +0 -0
  59. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages-iPhone-60x45pt@3x.png +0 -0
  60. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages27x20pt@2x.png +0 -0
  61. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages27x20pt@3x.png +0 -0
  62. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages32x24pt@2x.png +0 -0
  63. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/Messages32x24pt@3x.png +0 -0
  64. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/iPad-Settings-29pt@2x.png +0 -0
  65. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/iPhone-Settings-29pt@3x.png +0 -0
  66. sticker_convert/ios-message-stickers-template/stickers StickerPackExtension/Stickers.xcstickers/iMessage App Icon.stickersiconset/iPhone-settings-29pt@2x.png +0 -0
  67. sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.pbxproj +364 -364
  68. sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/contents.xcworkspacedata +7 -7
  69. sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -8
  70. sticker_convert/ios-message-stickers-template/stickers.xcodeproj/project.xcworkspace/xcuserdata/niklaspeterson.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  71. sticker_convert/ios-message-stickers-template/stickers.xcodeproj/xcuserdata/niklaspeterson.xcuserdatad/xcschemes/xcschememanagement.plist +14 -14
  72. sticker_convert/job.py +279 -179
  73. sticker_convert/job_option.py +15 -2
  74. sticker_convert/locales/en_US/LC_MESSAGES/base.mo +0 -0
  75. sticker_convert/locales/ja_JP/LC_MESSAGES/base.mo +0 -0
  76. sticker_convert/locales/zh_CN/LC_MESSAGES/base.mo +0 -0
  77. sticker_convert/locales/zh_TW/LC_MESSAGES/base.mo +0 -0
  78. sticker_convert/py.typed +0 -0
  79. sticker_convert/resources/NotoColorEmoji.ttf +0 -0
  80. sticker_convert/resources/compression.json +220 -16
  81. sticker_convert/resources/emoji.json +527 -77
  82. sticker_convert/resources/help.ja_JP.json +88 -0
  83. sticker_convert/resources/help.json +24 -10
  84. sticker_convert/resources/help.zh_CN.json +88 -0
  85. sticker_convert/resources/help.zh_TW.json +88 -0
  86. sticker_convert/resources/input.ja_JP.json +74 -0
  87. sticker_convert/resources/input.json +121 -71
  88. sticker_convert/resources/input.zh_CN.json +74 -0
  89. sticker_convert/resources/input.zh_TW.json +74 -0
  90. sticker_convert/resources/memdump_linux.sh +25 -0
  91. sticker_convert/resources/memdump_windows.ps1 +8 -0
  92. sticker_convert/resources/output.ja_JP.json +38 -0
  93. sticker_convert/resources/output.json +24 -0
  94. sticker_convert/resources/output.zh_CN.json +38 -0
  95. sticker_convert/resources/output.zh_TW.json +38 -0
  96. sticker_convert/uploaders/compress_wastickers.py +186 -156
  97. sticker_convert/uploaders/upload_base.py +44 -35
  98. sticker_convert/uploaders/upload_signal.py +218 -173
  99. sticker_convert/uploaders/upload_telegram.py +353 -388
  100. sticker_convert/uploaders/upload_viber.py +178 -0
  101. sticker_convert/uploaders/xcode_imessage.py +295 -285
  102. sticker_convert/utils/callback.py +238 -6
  103. sticker_convert/utils/chrome_remotedebug.py +219 -0
  104. sticker_convert/utils/chromiums/linux.py +52 -0
  105. sticker_convert/utils/chromiums/osx.py +68 -0
  106. sticker_convert/utils/chromiums/windows.py +45 -0
  107. sticker_convert/utils/emoji.py +28 -0
  108. sticker_convert/utils/files/json_resources_loader.py +24 -19
  109. sticker_convert/utils/files/metadata_handler.py +8 -7
  110. sticker_convert/utils/files/run_bin.py +1 -1
  111. sticker_convert/utils/media/codec_info.py +99 -67
  112. sticker_convert/utils/media/format_verify.py +33 -20
  113. sticker_convert/utils/process.py +231 -0
  114. sticker_convert/utils/translate.py +108 -0
  115. sticker_convert/utils/url_detect.py +40 -33
  116. sticker_convert/version.py +1 -1
  117. {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info}/METADATA +189 -96
  118. sticker_convert-2.17.0.0.dist-info/RECORD +138 -0
  119. {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info}/WHEEL +1 -1
  120. sticker_convert/utils/auth/get_signal_auth.py +0 -129
  121. sticker_convert-2.8.12.dist-info/RECORD +0 -101
  122. {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info}/entry_points.txt +0 -0
  123. {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info/licenses}/LICENSE +0 -0
  124. {sticker_convert-2.8.12.dist-info → sticker_convert-2.17.0.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ from pathlib import Path
5
+ from typing import Any, List, Optional, Tuple
6
+ from urllib import parse
7
+
8
+ import requests
9
+ from bs4 import BeautifulSoup
10
+
11
+ from sticker_convert.downloaders.download_base import DownloadBase
12
+ from sticker_convert.job_option import CredOption, InputOption
13
+ from sticker_convert.utils.callback import CallbackProtocol, CallbackReturn
14
+ from sticker_convert.utils.files.metadata_handler import MetadataHandler
15
+ from sticker_convert.utils.translate import I
16
+
17
+ # Reference: https://github.com/star-39/moe-sticker-bot/issues/49
18
+
19
+
20
+ class DownloadOgq(DownloadBase):
21
+ def __init__(self, *args: Any, **kwargs: Any) -> None:
22
+ super().__init__(*args, **kwargs)
23
+ self.headers = {"User-Agent": "Mozilla/5.0"}
24
+
25
+ def download_stickers_ogq(self) -> Tuple[int, int]:
26
+ url_parse = parse.urlparse(self.url)
27
+ if (
28
+ url_parse.netloc != "ogqmarket.naver.com"
29
+ or url_parse.path.startswith("/artworks/sticker/detail") is False
30
+ ):
31
+ self.cb.put(I("Invalid url: {}").format(self.url))
32
+ artwork_id = {
33
+ i.split("=")[0]: i.split("=")[1] for i in url_parse.query.split("&")
34
+ }["artworkId"]
35
+
36
+ html = requests.get(self.url, headers=self.headers).text
37
+ soup = BeautifulSoup(html, "html.parser")
38
+
39
+ author_tag = soup.select_one("div.info div.nickname span") # type: ignore
40
+ author = author_tag.text.strip() if author_tag else "OGQ"
41
+ title_tag = soup.select_one("div.header div div.title p") # type: ignore
42
+ title = title_tag.text.strip() if title_tag else artwork_id
43
+
44
+ seen: List[str] = []
45
+ imgs: List[str] = []
46
+ targets: List[Tuple[str, Path]] = []
47
+ n = 0
48
+ for img in soup.find_all("img", alt="sticker-detail-image-prevew"):
49
+ src = img.get("src")
50
+ if not src:
51
+ continue
52
+ src = src.split("?")[0]
53
+ if src in seen:
54
+ continue
55
+ seen.append(src)
56
+ imgs.append(src)
57
+ sticker_url = f"{src}?type=ma480_480"
58
+ sticker_url_parse = parse.urlparse(sticker_url)
59
+ ext = sticker_url_parse.path.split(".")[-1]
60
+ if sticker_url_parse.path.split("/")[-1].startswith("original_"):
61
+ path = self.out_dir / f"{n}.{ext}"
62
+ else:
63
+ path = self.out_dir / f"cover.{ext}"
64
+ targets.append((sticker_url, path))
65
+ n += 1
66
+
67
+ results = self.download_multiple_files(targets)
68
+ MetadataHandler.set_metadata(self.out_dir, title=title, author=author)
69
+
70
+ return len(results.values()), len(targets)
71
+
72
+ @staticmethod
73
+ def start(
74
+ opt_input: InputOption,
75
+ opt_cred: Optional[CredOption],
76
+ cb: CallbackProtocol,
77
+ cb_return: CallbackReturn,
78
+ ) -> Tuple[int, int]:
79
+ downloader = DownloadOgq(opt_input, opt_cred, cb, cb_return)
80
+ return downloader.download_stickers_ogq()
@@ -1,92 +1,108 @@
1
- #!/usr/bin/env python3
2
- from pathlib import Path
3
- from typing import Dict, Optional
4
-
5
- import anyio
6
- from signalstickers_client.errors import SignalException
7
- from signalstickers_client.models import StickerPack
8
- from signalstickers_client.stickersclient import StickersClient
9
-
10
- from sticker_convert.downloaders.download_base import DownloadBase
11
- from sticker_convert.job_option import CredOption
12
- from sticker_convert.utils.callback import CallbackProtocol, CallbackReturn
13
- from sticker_convert.utils.files.metadata_handler import MetadataHandler
14
- from sticker_convert.utils.media.codec_info import CodecInfo
15
-
16
-
17
- class DownloadSignal(DownloadBase):
18
- # def __init__(self, *args: Any, **kwargs: Any) -> None:
19
- # super().__init__(*args, **kwargs)
20
-
21
- @staticmethod
22
- async def get_pack(pack_id: str, pack_key: str) -> StickerPack:
23
- async with StickersClient() as client:
24
- pack = await client.get_pack(pack_id, pack_key)
25
-
26
- return pack
27
-
28
- def save_stickers(self, pack: StickerPack) -> None:
29
- self.cb.put(
30
- (
31
- "bar",
32
- None,
33
- {
34
- "set_progress_mode": "determinate",
35
- "steps": len(pack.stickers),
36
- },
37
- )
38
- )
39
-
40
- emoji_dict: Dict[str, str] = {}
41
- for sticker in pack.stickers:
42
- f_id = str(sticker.id).zfill(3)
43
- f_path = Path(self.out_dir, f_id)
44
- with open(f_path, "wb") as f:
45
- f.write(sticker.image_data) # type: ignore
46
-
47
- emoji_dict[f_id] = sticker.emoji # type: ignore
48
-
49
- codec = CodecInfo.get_file_codec(f_path)
50
- if codec == "":
51
- msg = f"Warning: Downloaded {f_path} but cannot get file codec"
52
- self.cb.put(msg)
53
- else:
54
- f_path_new = Path(f"{f_path}.{codec}")
55
- f_path.rename(f_path_new)
56
- msg = f"Downloaded {f_id}.{codec}"
57
- self.cb.put(msg)
58
-
59
- self.cb.put("update_bar")
60
-
61
- MetadataHandler.set_metadata(
62
- self.out_dir, title=pack.title, author=pack.author, emoji_dict=emoji_dict
63
- )
64
-
65
- def download_stickers_signal(self) -> bool:
66
- if "signal.art" not in self.url:
67
- self.cb.put("Download failed: Unrecognized URL format")
68
- return False
69
-
70
- pack_id = self.url.split("#pack_id=")[1].split("&pack_key=")[0]
71
- pack_key = self.url.split("&pack_key=")[1]
72
-
73
- try:
74
- pack = anyio.run(DownloadSignal.get_pack, pack_id, pack_key)
75
- except SignalException as e:
76
- self.cb.put(f"Failed to download pack due to {repr(e)}")
77
- return False
78
-
79
- self.save_stickers(pack)
80
-
81
- return True
82
-
83
- @staticmethod
84
- def start(
85
- url: str,
86
- out_dir: Path,
87
- opt_cred: Optional[CredOption],
88
- cb: CallbackProtocol,
89
- cb_return: CallbackReturn,
90
- ) -> bool:
91
- downloader = DownloadSignal(url, out_dir, opt_cred, cb, cb_return)
92
- return downloader.download_stickers_signal()
1
+ #!/usr/bin/env python3
2
+ from pathlib import Path
3
+ from typing import Dict, Optional, Tuple
4
+
5
+ import anyio
6
+ from signalstickers_client.errors import SignalException
7
+ from signalstickers_client.models import StickerPack
8
+ from signalstickers_client.stickersclient import StickersClient
9
+
10
+ from sticker_convert.downloaders.download_base import DownloadBase
11
+ from sticker_convert.job_option import CredOption, InputOption
12
+ from sticker_convert.utils.callback import CallbackProtocol, CallbackReturn
13
+ from sticker_convert.utils.files.metadata_handler import MetadataHandler
14
+ from sticker_convert.utils.media.codec_info import CodecInfo
15
+ from sticker_convert.utils.translate import I
16
+
17
+
18
+ class DownloadSignal(DownloadBase):
19
+ # def __init__(self, *args: Any, **kwargs: Any) -> None:
20
+ # super().__init__(*args, **kwargs)
21
+
22
+ @staticmethod
23
+ async def get_pack(pack_id: str, pack_key: str) -> StickerPack:
24
+ async with StickersClient() as client:
25
+ pack = await client.get_pack(pack_id, pack_key)
26
+
27
+ return pack
28
+
29
+ def save_stickers(self, pack: StickerPack) -> None:
30
+ self.cb.put(
31
+ (
32
+ "bar",
33
+ None,
34
+ {
35
+ "set_progress_mode": "determinate",
36
+ "steps": len(pack.stickers),
37
+ },
38
+ )
39
+ )
40
+
41
+ emoji_dict: Dict[str, str] = {}
42
+ for sticker in pack.stickers:
43
+ f_id = str(sticker.id).zfill(3)
44
+ f_path = Path(self.out_dir, f_id)
45
+ with open(f_path, "wb") as f:
46
+ f.write(sticker.image_data) # type: ignore
47
+
48
+ emoji_dict[f_id] = sticker.emoji # type: ignore
49
+
50
+ codec = CodecInfo.get_file_codec(f_path)
51
+ if codec == "":
52
+ msg = I("Warning: Downloaded {} but cannot get file codec").format(
53
+ f_path
54
+ )
55
+ self.cb.put(msg)
56
+ else:
57
+ f_path_new = Path(f"{f_path}.{codec}")
58
+ f_path.rename(f_path_new)
59
+ msg = I("Downloaded {}.{}").format(f_id, codec)
60
+ self.cb.put(msg)
61
+
62
+ self.cb.put("update_bar")
63
+
64
+ if pack.cover is not None and pack.cover.image_data is not None:
65
+ cover_path = Path(self.out_dir, "cover")
66
+ with open(cover_path, "wb") as f:
67
+ f.write(pack.cover.image_data)
68
+
69
+ cover_codec = CodecInfo.get_file_codec(cover_path)
70
+ if cover_codec == "":
71
+ cover_codec = "png"
72
+ cover_path_new = Path(self.out_dir, f"cover.{cover_codec}")
73
+ cover_path.rename(cover_path_new)
74
+ self.cb.put(I("Downloaded cover.{}").format(cover_codec))
75
+
76
+ MetadataHandler.set_metadata(
77
+ self.out_dir, title=pack.title, author=pack.author, emoji_dict=emoji_dict
78
+ )
79
+
80
+ def download_stickers_signal(self) -> Tuple[int, int]:
81
+ if "signal.art" not in self.url and not self.url.startswith(
82
+ "sgnl://addstickers/"
83
+ ):
84
+ self.cb.put(I("Download failed: Unrecognized URL format"))
85
+ return 0, 0
86
+
87
+ pack_id = self.url.split("pack_id=")[1].split("&pack_key=")[0]
88
+ pack_key = self.url.split("&pack_key=")[1]
89
+
90
+ try:
91
+ pack = anyio.run(DownloadSignal.get_pack, pack_id, pack_key)
92
+ except SignalException as e:
93
+ self.cb.put(I("Failed to download pack. Reason: {}").format(repr(e)))
94
+ return 0, 0
95
+
96
+ self.save_stickers(pack)
97
+
98
+ return len(pack.stickers), len(pack.stickers)
99
+
100
+ @staticmethod
101
+ def start(
102
+ opt_input: InputOption,
103
+ opt_cred: Optional[CredOption],
104
+ cb: CallbackProtocol,
105
+ cb_return: CallbackReturn,
106
+ ) -> Tuple[int, int]:
107
+ downloader = DownloadSignal(opt_input, opt_cred, cb, cb_return)
108
+ return downloader.download_stickers_signal()
@@ -1,130 +1,56 @@
1
- #!/usr/bin/env python3
2
- from pathlib import Path
3
- from typing import Dict, Optional, Union
4
- from urllib.parse import urlparse
5
-
6
- import anyio
7
- from telegram import PhotoSize, Sticker, StickerSet
8
- from telegram.error import TelegramError
9
- from telegram.ext import AIORateLimiter, ApplicationBuilder
10
-
11
- from sticker_convert.downloaders.download_base import DownloadBase
12
- from sticker_convert.job_option import CredOption
13
- from sticker_convert.utils.callback import CallbackProtocol, CallbackReturn
14
- from sticker_convert.utils.files.metadata_handler import MetadataHandler
15
-
16
-
17
- class DownloadTelegram(DownloadBase):
18
- # def __init__(self, *args: Any, **kwargs: Any) -> None:
19
- # super().__init__(*args, **kwargs)
20
-
21
- def download_stickers_telegram(self) -> bool:
22
- self.token = ""
23
-
24
- if self.opt_cred:
25
- self.token = self.opt_cred.telegram_token.strip()
26
- if not self.token:
27
- self.cb.put("Download failed: Token required for downloading from telegram")
28
- return False
29
-
30
- if not ("telegram.me" in self.url or "t.me" in self.url):
31
- self.cb.put("Download failed: Unrecognized URL format")
32
- return False
33
-
34
- self.title = Path(urlparse(self.url).path).name
35
-
36
- self.emoji_dict: Dict[str, str] = {}
37
-
38
- return anyio.run(self.save_stickers)
39
-
40
- async def save_stickers(self) -> bool:
41
- timeout = 30
42
- application = ( # type: ignore
43
- ApplicationBuilder()
44
- .token(self.token)
45
- .rate_limiter(AIORateLimiter(max_retries=3))
46
- .connect_timeout(timeout)
47
- .pool_timeout(timeout)
48
- .read_timeout(timeout)
49
- .write_timeout(timeout)
50
- .connection_pool_size(20)
51
- .build()
52
- )
53
-
54
- async with application:
55
- bot = application.bot
56
- try:
57
- sticker_set: StickerSet = await bot.get_sticker_set(
58
- self.title,
59
- read_timeout=timeout,
60
- write_timeout=timeout,
61
- connect_timeout=timeout,
62
- pool_timeout=timeout,
63
- )
64
- except TelegramError as e:
65
- self.cb.put(
66
- f"Failed to download telegram sticker set {self.title} due to: {e}"
67
- )
68
- return False
69
-
70
- self.cb.put(
71
- (
72
- "bar",
73
- None,
74
- {
75
- "set_progress_mode": "determinate",
76
- "steps": len(sticker_set.stickers),
77
- },
78
- )
79
- )
80
-
81
- async def download_sticker(
82
- sticker: Union[PhotoSize, Sticker], f_id: str
83
- ) -> None:
84
- sticker_file = await sticker.get_file(
85
- read_timeout=timeout,
86
- write_timeout=timeout,
87
- connect_timeout=timeout,
88
- pool_timeout=timeout,
89
- )
90
- fpath = sticker_file.file_path
91
- assert fpath is not None
92
- ext = Path(fpath).suffix
93
- f_name = f_id + ext
94
- f_path = Path(self.out_dir, f_name)
95
- await sticker_file.download_to_drive(
96
- custom_path=f_path,
97
- read_timeout=timeout,
98
- write_timeout=timeout,
99
- connect_timeout=timeout,
100
- pool_timeout=timeout,
101
- )
102
- if isinstance(sticker, Sticker) and sticker.emoji is not None:
103
- self.emoji_dict[f_id] = sticker.emoji
104
- self.cb.put(f"Downloaded {f_name}")
105
- if f_id != "cover":
106
- self.cb.put("update_bar")
107
-
108
- async with anyio.create_task_group() as tg:
109
- for num, sticker in enumerate(sticker_set.stickers):
110
- f_id = str(num).zfill(3)
111
- tg.start_soon(download_sticker, sticker, f_id)
112
-
113
- if sticker_set.thumbnail is not None:
114
- tg.start_soon(download_sticker, sticker_set.thumbnail, "cover")
115
-
116
- MetadataHandler.set_metadata(
117
- self.out_dir, title=self.title, emoji_dict=self.emoji_dict
118
- )
119
- return True
120
-
121
- @staticmethod
122
- def start(
123
- url: str,
124
- out_dir: Path,
125
- opt_cred: Optional[CredOption],
126
- cb: CallbackProtocol,
127
- cb_return: CallbackReturn,
128
- ) -> bool:
129
- downloader = DownloadTelegram(url, out_dir, opt_cred, cb, cb_return)
130
- return downloader.download_stickers_telegram()
1
+ #!/usr/bin/env python3
2
+ from pathlib import Path
3
+ from typing import Optional, Tuple
4
+ from urllib.parse import urlparse
5
+
6
+ import anyio
7
+
8
+ from sticker_convert.auth.telegram_api import BotAPI, TelegramAPI, TelethonAPI
9
+ from sticker_convert.downloaders.download_base import DownloadBase
10
+ from sticker_convert.job_option import CredOption, InputOption
11
+ from sticker_convert.utils.callback import CallbackProtocol, CallbackReturn
12
+ from sticker_convert.utils.files.metadata_handler import MetadataHandler
13
+ from sticker_convert.utils.translate import I
14
+
15
+
16
+ class DownloadTelegram(DownloadBase):
17
+ # def __init__(self, *args: Any, **kwargs: Any) -> None:
18
+ # super().__init__(*args, **kwargs)
19
+
20
+ def download_stickers_telegram(self) -> Tuple[int, int]:
21
+ if not ("telegram.me" in self.url or "t.me" in self.url):
22
+ self.cb.put(I("Download failed: Unrecognized URL format"))
23
+ return 0, 0
24
+
25
+ return anyio.run(self.save_stickers)
26
+
27
+ async def save_stickers(self) -> Tuple[int, int]:
28
+ tg_api: TelegramAPI
29
+ if self.input_option.endswith("telethon"):
30
+ tg_api = TelethonAPI()
31
+ else:
32
+ tg_api = BotAPI()
33
+
34
+ if self.opt_cred is None:
35
+ self.cb.put(I("Download failed: No credentials"))
36
+ return 0, 0
37
+
38
+ success = await tg_api.setup(self.opt_cred, False, self.cb, self.cb_return)
39
+ if success is False:
40
+ self.cb.put(I("Download failed: Invalid credentials"))
41
+ return 0, 0
42
+
43
+ title = Path(urlparse(self.url).path).name
44
+ results, emoji_dict = await tg_api.pack_dl(title, self.out_dir)
45
+ MetadataHandler.set_metadata(self.out_dir, title=title, emoji_dict=emoji_dict)
46
+ return sum(results.values()), len(results)
47
+
48
+ @staticmethod
49
+ def start(
50
+ opt_input: InputOption,
51
+ opt_cred: Optional[CredOption],
52
+ cb: CallbackProtocol,
53
+ cb_return: CallbackReturn,
54
+ ) -> Tuple[int, int]:
55
+ downloader = DownloadTelegram(opt_input, opt_cred, cb, cb_return)
56
+ return downloader.download_stickers_telegram()