yaju-bot 0.1.0__tar.gz
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.
- yaju_bot-0.1.0/PKG-INFO +43 -0
- yaju_bot-0.1.0/README.md +28 -0
- yaju_bot-0.1.0/pyproject.toml +30 -0
- yaju_bot-0.1.0/python/yaju_bot/__init__.py +203 -0
- yaju_bot-0.1.0/python/yaju_bot.egg-info/PKG-INFO +43 -0
- yaju_bot-0.1.0/python/yaju_bot.egg-info/SOURCES.txt +8 -0
- yaju_bot-0.1.0/python/yaju_bot.egg-info/dependency_links.txt +1 -0
- yaju_bot-0.1.0/python/yaju_bot.egg-info/top_level.txt +2 -0
- yaju_bot-0.1.0/python/yajuu_bot/__init__.py +2 -0
- yaju_bot-0.1.0/setup.cfg +4 -0
yaju_bot-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yaju-bot
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Go-powered Discord conversation intruder bot with a Python launcher
|
|
5
|
+
Author: dtmpm3485
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dtmpm3485/yaju-bot
|
|
8
|
+
Project-URL: Repository, https://github.com/dtmpm3485/yaju-bot
|
|
9
|
+
Keywords: discord,bot,go,python,meme
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Go
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# yaju-bot
|
|
17
|
+
|
|
18
|
+
Discordの会話にたまに返信で乱入するBotです。特定キーワードやメンションでも呼べます。
|
|
19
|
+
|
|
20
|
+
## インストール
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install yaju-bot
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 使い方
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from yaju_bot import run
|
|
30
|
+
|
|
31
|
+
run("DISCORD_BOT_TOKEN")
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 主なコマンド
|
|
35
|
+
|
|
36
|
+
- `/yaju on` / `/yaju off`
|
|
37
|
+
- `/yaju status` / `/yaju stats`
|
|
38
|
+
- `/yaju quote` / `/yaju test`
|
|
39
|
+
- `/yaju mode` / `/yaju chance` / `/yaju cooldown`
|
|
40
|
+
- `/yaju keyword add|remove|list|reset`
|
|
41
|
+
- `/yaju channel add|remove|list|clear`
|
|
42
|
+
|
|
43
|
+
初期呼び出しワード: `野獣先輩` `やじゅ` `やじゅせん` `yaju` `yajuu` `114514` `810` `淫夢`
|
yaju_bot-0.1.0/README.md
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# yaju-bot
|
|
2
|
+
|
|
3
|
+
Discordの会話にたまに返信で乱入するBotです。特定キーワードやメンションでも呼べます。
|
|
4
|
+
|
|
5
|
+
## インストール
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install yaju-bot
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 使い方
|
|
12
|
+
|
|
13
|
+
```python
|
|
14
|
+
from yaju_bot import run
|
|
15
|
+
|
|
16
|
+
run("DISCORD_BOT_TOKEN")
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 主なコマンド
|
|
20
|
+
|
|
21
|
+
- `/yaju on` / `/yaju off`
|
|
22
|
+
- `/yaju status` / `/yaju stats`
|
|
23
|
+
- `/yaju quote` / `/yaju test`
|
|
24
|
+
- `/yaju mode` / `/yaju chance` / `/yaju cooldown`
|
|
25
|
+
- `/yaju keyword add|remove|list|reset`
|
|
26
|
+
- `/yaju channel add|remove|list|clear`
|
|
27
|
+
|
|
28
|
+
初期呼び出しワード: `野獣先輩` `やじゅ` `やじゅせん` `yaju` `yajuu` `114514` `810` `淫夢`
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=75", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "yaju-bot"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Go-powered Discord conversation intruder bot with a Python launcher"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = {text = "MIT"}
|
|
12
|
+
authors = [{name = "dtmpm3485"}]
|
|
13
|
+
keywords = ["discord", "bot", "go", "python", "meme"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Go",
|
|
17
|
+
"Operating System :: OS Independent"
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
[project.urls]
|
|
21
|
+
Homepage = "https://github.com/dtmpm3485/yaju-bot"
|
|
22
|
+
Repository = "https://github.com/dtmpm3485/yaju-bot"
|
|
23
|
+
|
|
24
|
+
[tool.setuptools]
|
|
25
|
+
package-dir = {"" = "python"}
|
|
26
|
+
include-package-data = true
|
|
27
|
+
|
|
28
|
+
[tool.setuptools.packages.find]
|
|
29
|
+
where = ["python"]
|
|
30
|
+
include = ["yaju_bot*", "yajuu_bot*"]
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"""Python launcher for the Go-powered yaju-bot."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import hashlib
|
|
6
|
+
import os
|
|
7
|
+
import platform
|
|
8
|
+
import shutil
|
|
9
|
+
import stat
|
|
10
|
+
import subprocess
|
|
11
|
+
import sys
|
|
12
|
+
import tarfile
|
|
13
|
+
import tempfile
|
|
14
|
+
import urllib.error
|
|
15
|
+
import urllib.request
|
|
16
|
+
import zipfile
|
|
17
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from typing import Optional
|
|
20
|
+
|
|
21
|
+
__all__ = ["run"]
|
|
22
|
+
|
|
23
|
+
_PACKAGE = "yaju-bot"
|
|
24
|
+
_REPO = "dtmpm3485/yaju-bot"
|
|
25
|
+
_FALLBACK_VERSION = "0.1.0"
|
|
26
|
+
|
|
27
|
+
try:
|
|
28
|
+
__version__ = version(_PACKAGE)
|
|
29
|
+
except PackageNotFoundError:
|
|
30
|
+
__version__ = _FALLBACK_VERSION
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _cache_root() -> Path:
|
|
34
|
+
override = os.environ.get("YAJU_BOT_CACHE")
|
|
35
|
+
if override:
|
|
36
|
+
return Path(override).expanduser()
|
|
37
|
+
if os.name == "nt" and os.environ.get("LOCALAPPDATA"):
|
|
38
|
+
return Path(os.environ["LOCALAPPDATA"]) / "yaju-bot" / "cache"
|
|
39
|
+
xdg = os.environ.get("XDG_CACHE_HOME")
|
|
40
|
+
if xdg:
|
|
41
|
+
return Path(xdg) / "yaju-bot"
|
|
42
|
+
return Path.home() / ".cache" / "yaju-bot"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _platform_asset_for(system: str, machine: str) -> tuple[str, str]:
|
|
46
|
+
system = system.lower()
|
|
47
|
+
machine = machine.lower()
|
|
48
|
+
arch_map = {
|
|
49
|
+
"x86_64": "amd64",
|
|
50
|
+
"amd64": "amd64",
|
|
51
|
+
"aarch64": "arm64",
|
|
52
|
+
"arm64": "arm64",
|
|
53
|
+
"armv7l": "armv7",
|
|
54
|
+
"armv7": "armv7",
|
|
55
|
+
}
|
|
56
|
+
arch = arch_map.get(machine)
|
|
57
|
+
if arch is None:
|
|
58
|
+
raise RuntimeError(f"unsupported CPU architecture: {machine}")
|
|
59
|
+
|
|
60
|
+
if system == "linux":
|
|
61
|
+
os_name = "linux"
|
|
62
|
+
ext = ".tar.gz"
|
|
63
|
+
elif system == "darwin":
|
|
64
|
+
if arch == "armv7":
|
|
65
|
+
raise RuntimeError("unsupported macOS architecture: armv7")
|
|
66
|
+
os_name = "darwin"
|
|
67
|
+
ext = ".tar.gz"
|
|
68
|
+
elif system == "windows":
|
|
69
|
+
if arch == "armv7":
|
|
70
|
+
raise RuntimeError("unsupported Windows architecture: armv7")
|
|
71
|
+
os_name = "windows"
|
|
72
|
+
ext = ".zip"
|
|
73
|
+
else:
|
|
74
|
+
raise RuntimeError(f"unsupported operating system: {system}")
|
|
75
|
+
|
|
76
|
+
return f"yaju-bot-{os_name}-{arch}{ext}", "yaju-bot.exe" if os_name == "windows" else "yaju-bot"
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def _platform_asset() -> tuple[str, str]:
|
|
80
|
+
return _platform_asset_for(platform.system(), platform.machine())
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _request_bytes(url: str) -> bytes:
|
|
84
|
+
request = urllib.request.Request(url, headers={"User-Agent": f"yaju-bot/{__version__}"})
|
|
85
|
+
with urllib.request.urlopen(request, timeout=30) as response:
|
|
86
|
+
return response.read()
|
|
87
|
+
|
|
88
|
+
|
|
89
|
+
def _expected_checksum(checksums: bytes, asset_name: str) -> str:
|
|
90
|
+
for raw_line in checksums.decode("utf-8").splitlines():
|
|
91
|
+
parts = raw_line.strip().split()
|
|
92
|
+
if len(parts) >= 2 and parts[-1].lstrip("*") == asset_name:
|
|
93
|
+
digest = parts[0].lower()
|
|
94
|
+
if len(digest) == 64 and all(ch in "0123456789abcdef" for ch in digest):
|
|
95
|
+
return digest
|
|
96
|
+
raise RuntimeError(f"checksum not found for release asset: {asset_name}")
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _download_release_binary() -> Path:
|
|
100
|
+
asset_name, binary_name = _platform_asset()
|
|
101
|
+
cache_dir = _cache_root() / __version__
|
|
102
|
+
binary = cache_dir / binary_name
|
|
103
|
+
if binary.is_file():
|
|
104
|
+
return binary
|
|
105
|
+
|
|
106
|
+
tag = f"v{__version__}"
|
|
107
|
+
base = f"https://github.com/{_REPO}/releases/download/{tag}"
|
|
108
|
+
try:
|
|
109
|
+
checksums = _request_bytes(f"{base}/checksums.txt")
|
|
110
|
+
archive = _request_bytes(f"{base}/{asset_name}")
|
|
111
|
+
except (urllib.error.URLError, TimeoutError, OSError) as exc:
|
|
112
|
+
raise RuntimeError(f"failed to download yaju-bot {tag}: {exc}") from exc
|
|
113
|
+
|
|
114
|
+
expected = _expected_checksum(checksums, asset_name)
|
|
115
|
+
actual = hashlib.sha256(archive).hexdigest()
|
|
116
|
+
if actual != expected:
|
|
117
|
+
raise RuntimeError(f"release checksum mismatch for {asset_name}")
|
|
118
|
+
|
|
119
|
+
cache_dir.mkdir(parents=True, exist_ok=True)
|
|
120
|
+
with tempfile.TemporaryDirectory(prefix="yaju-bot-") as tmp_name:
|
|
121
|
+
tmp = Path(tmp_name)
|
|
122
|
+
archive_path = tmp / asset_name
|
|
123
|
+
archive_path.write_bytes(archive)
|
|
124
|
+
extracted = tmp / binary_name
|
|
125
|
+
|
|
126
|
+
if asset_name.endswith(".zip"):
|
|
127
|
+
with zipfile.ZipFile(archive_path) as zf:
|
|
128
|
+
try:
|
|
129
|
+
data = zf.read(binary_name)
|
|
130
|
+
except KeyError as exc:
|
|
131
|
+
raise RuntimeError(f"{binary_name} is missing from {asset_name}") from exc
|
|
132
|
+
extracted.write_bytes(data)
|
|
133
|
+
else:
|
|
134
|
+
with tarfile.open(archive_path, "r:gz") as tf:
|
|
135
|
+
try:
|
|
136
|
+
member = tf.getmember(binary_name)
|
|
137
|
+
except KeyError as exc:
|
|
138
|
+
raise RuntimeError(f"{binary_name} is missing from {asset_name}") from exc
|
|
139
|
+
source = tf.extractfile(member)
|
|
140
|
+
if source is None:
|
|
141
|
+
raise RuntimeError(f"failed to read {binary_name} from {asset_name}")
|
|
142
|
+
extracted.write_bytes(source.read())
|
|
143
|
+
|
|
144
|
+
staged = cache_dir / f".{binary_name}.{os.getpid()}.tmp"
|
|
145
|
+
try:
|
|
146
|
+
shutil.copyfile(extracted, staged)
|
|
147
|
+
if os.name != "nt":
|
|
148
|
+
staged.chmod(staged.stat().st_mode | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
|
149
|
+
os.replace(staged, binary)
|
|
150
|
+
finally:
|
|
151
|
+
try:
|
|
152
|
+
staged.unlink()
|
|
153
|
+
except FileNotFoundError:
|
|
154
|
+
pass
|
|
155
|
+
|
|
156
|
+
return binary
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
def _source_checkout() -> Optional[Path]:
|
|
160
|
+
here = Path(__file__).resolve()
|
|
161
|
+
for parent in here.parents:
|
|
162
|
+
if (parent / "go.mod").is_file() and (parent / "cmd" / "yaju-bot").is_dir():
|
|
163
|
+
return parent
|
|
164
|
+
return None
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def _resolve_command() -> tuple[list[str], Optional[str]]:
|
|
168
|
+
override = os.environ.get("YAJU_BOT_BIN")
|
|
169
|
+
if override:
|
|
170
|
+
return [override], None
|
|
171
|
+
|
|
172
|
+
source = _source_checkout()
|
|
173
|
+
go = shutil.which("go")
|
|
174
|
+
if source is not None and go is not None:
|
|
175
|
+
return [go, "run", "./cmd/yaju-bot"], str(source)
|
|
176
|
+
|
|
177
|
+
try:
|
|
178
|
+
return [str(_download_release_binary())], None
|
|
179
|
+
except RuntimeError as download_error:
|
|
180
|
+
if go is not None:
|
|
181
|
+
return [go, "run", f"github.com/{_REPO}/cmd/yaju-bot@v{__version__}"], None
|
|
182
|
+
raise RuntimeError(
|
|
183
|
+
f"{download_error}. Install Go as a fallback, or set YAJU_BOT_BIN to a yaju-bot executable."
|
|
184
|
+
) from download_error
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def run(token: str, *, data_dir: str | os.PathLike[str] | None = None) -> None:
|
|
188
|
+
"""Start yaju-bot and block until it exits."""
|
|
189
|
+
if not isinstance(token, str) or not token.strip():
|
|
190
|
+
raise ValueError("token must be a non-empty Discord bot token")
|
|
191
|
+
|
|
192
|
+
env = os.environ.copy()
|
|
193
|
+
env["DISCORD_TOKEN"] = token.strip()
|
|
194
|
+
if data_dir is not None:
|
|
195
|
+
env["YAJU_DATA_DIR"] = os.fspath(data_dir)
|
|
196
|
+
|
|
197
|
+
command, cwd = _resolve_command()
|
|
198
|
+
try:
|
|
199
|
+
completed = subprocess.run(command, env=env, cwd=cwd, check=False)
|
|
200
|
+
except KeyboardInterrupt:
|
|
201
|
+
return
|
|
202
|
+
if completed.returncode != 0:
|
|
203
|
+
raise RuntimeError(f"yaju-bot exited with status {completed.returncode}")
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: yaju-bot
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Go-powered Discord conversation intruder bot with a Python launcher
|
|
5
|
+
Author: dtmpm3485
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dtmpm3485/yaju-bot
|
|
8
|
+
Project-URL: Repository, https://github.com/dtmpm3485/yaju-bot
|
|
9
|
+
Keywords: discord,bot,go,python,meme
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Go
|
|
12
|
+
Classifier: Operating System :: OS Independent
|
|
13
|
+
Requires-Python: >=3.10
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# yaju-bot
|
|
17
|
+
|
|
18
|
+
Discordの会話にたまに返信で乱入するBotです。特定キーワードやメンションでも呼べます。
|
|
19
|
+
|
|
20
|
+
## インストール
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install yaju-bot
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## 使い方
|
|
27
|
+
|
|
28
|
+
```python
|
|
29
|
+
from yaju_bot import run
|
|
30
|
+
|
|
31
|
+
run("DISCORD_BOT_TOKEN")
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## 主なコマンド
|
|
35
|
+
|
|
36
|
+
- `/yaju on` / `/yaju off`
|
|
37
|
+
- `/yaju status` / `/yaju stats`
|
|
38
|
+
- `/yaju quote` / `/yaju test`
|
|
39
|
+
- `/yaju mode` / `/yaju chance` / `/yaju cooldown`
|
|
40
|
+
- `/yaju keyword add|remove|list|reset`
|
|
41
|
+
- `/yaju channel add|remove|list|clear`
|
|
42
|
+
|
|
43
|
+
初期呼び出しワード: `野獣先輩` `やじゅ` `やじゅせん` `yaju` `yajuu` `114514` `810` `淫夢`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
yaju_bot-0.1.0/setup.cfg
ADDED