Skip to content

Commit ffd09ba

Browse files
committed
Add the start of --create-new helper scripts
1 parent 5774dee commit ffd09ba

File tree

1 file changed

+141
-0
lines changed

1 file changed

+141
-0
lines changed

twitchio/__main__.py

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,13 @@
2323
"""
2424

2525
import argparse
26+
import os
27+
import pathlib
2628
import platform
2729
import re
2830
import sys
31+
import subprocess
32+
from typing import Callable
2933

3034
import aiohttp
3135

@@ -48,9 +52,87 @@
4852
parser = argparse.ArgumentParser(prog="twitchio")
4953
parser.add_argument("--version", action="store_true", help="Get version and debug information for TwitchIO.")
5054

55+
# TODO: Only uncomment for testing, until complete...
56+
# new_bot = parser.add_argument_group("Create Bot", "Create and generate bot boilerplate via an interactive walkthrough.")
57+
# new_bot.add_argument("--create-new", action="store_true", help="Start an interactive walkthrough.")
58+
5159
args = parser.parse_args()
5260

5361

62+
COMPONENT = """from typing import TYPE_CHECKING
63+
64+
import twitchio
65+
from twitchio.ext import commands
66+
67+
68+
if TYPE_CHECKING:
69+
from ..bot import Bot
70+
71+
72+
class GeneralComponent(commands.Component):
73+
def __init__(self, bot: Bot) -> None:
74+
self.bot = bot
75+
76+
@commands.command()
77+
async def hi(self, ctx: commands.Context) -> None:
78+
await ctx.send(f"Hello {ctx.author.mention}")
79+
80+
81+
async def setup(bot: Bot) -> None:
82+
await bot.add_component(GeneralComponent(bot))
83+
84+
85+
# This is an optional teardown coroutine for miscellaneous clean-up if necessary.
86+
async def teardown(bot: Bot) -> None: ...
87+
88+
"""
89+
90+
MAIN = """"""
91+
92+
BOOLS = {
93+
"y": True,
94+
"yes": True,
95+
"n": False,
96+
"no": False,
97+
"t": True,
98+
"true": True,
99+
"f": False,
100+
"false": False,
101+
"1": True,
102+
"0": False,
103+
}
104+
105+
106+
def bool_check(inp: str) -> bool | None:
107+
return BOOLS.get(inp.lower())
108+
109+
110+
def bool_validate(inp: str) -> bool:
111+
return BOOLS.get(inp.lower()) is not None
112+
113+
114+
def validate_input(inp: str, check: Callable[[str], bool] | None = None, *, error_msg: str | None = None) -> str:
115+
error_msg = error_msg or "Invalid input, please try again!"
116+
117+
while True:
118+
response = input(inp)
119+
if not check:
120+
break
121+
122+
try:
123+
result = check(response)
124+
except Exception:
125+
result = False
126+
127+
if result is False:
128+
print(error_msg, end="\n\n")
129+
continue
130+
131+
break
132+
133+
return response
134+
135+
54136
def get_version() -> str:
55137
version = ""
56138
with open("twitchio/__init__.py") as f:
@@ -99,5 +181,64 @@ def version_info() -> None:
99181
print(info)
100182

101183

184+
def install_packages(exe: pathlib.Path, starlette: bool | None = False) -> None:
185+
package = "twitchio" if not starlette else "twitchio[starlette]"
186+
subprocess.call([exe, "-m", "pip", "install", package, "--upgrade", "--no-cache"])
187+
188+
189+
def generate_venv() -> None:
190+
# Create the venv...
191+
subprocess.call([sys.executable, "-m", "venv", ".venv"])
192+
193+
system = platform.system()
194+
195+
if system == "Windows":
196+
exe = pathlib.Path(".venv") / "Scripts" / "python.exe"
197+
elif system in ["Darwin", "Linux"]:
198+
exe = pathlib.Path(".venv") / "bin" / "python"
199+
else:
200+
print("Unsupported operating system... Skipping package installation. Please manually install required packages.")
201+
return
202+
203+
starlette = bool_check(validate_input("Would you like to install the optional Starlette and Uvicorn packages? (y/N): ", bool_validate,))
204+
install_packages(exe, starlette)
205+
206+
207+
def generate_bot() -> ...:
208+
name = validate_input("Project name? (Leave blank to generate files in this directory): ")
209+
if name:
210+
dir = pathlib.Path(name)
211+
dir.mkdir(exist_ok=True)
212+
os.chdir(dir)
213+
else:
214+
dir = pathlib.Path.cwd()
215+
216+
if sys.prefix != sys.base_prefix:
217+
resp = bool_check(validate_input("No virtual environment used. Would you like to create one? (y/N): ", bool_validate,))
218+
219+
if resp:
220+
generate_venv()
221+
222+
components = bool_check(validate_input("Would you like to setup commands.Components? (y/N): ", bool_validate))
223+
if components:
224+
comp_dir = pathlib.Path("components")
225+
comp_dir.mkdir(exist_ok=True)
226+
227+
with open(comp_dir / "general.py", "w") as fp:
228+
fp.write(COMPONENT)
229+
230+
# TODO: .env
231+
# TODO: client details
232+
# TODO: fetch owner/bot IDs
233+
# with open(dir / "main.py", "w") as fp:
234+
# ...
235+
236+
# with open(dir / "bot.py", "w") as fp:
237+
# ...
238+
239+
102240
if args.version:
103241
version_info()
242+
243+
elif args.create_new:
244+
generate_bot()

0 commit comments

Comments
 (0)