Skip to content

Commit

Permalink
Rework twitch auth to use only user (#13)
Browse files Browse the repository at this point in the history
* Rework twitch auth to use only user

* Update build.yml

* Update build.yml
  • Loading branch information
WolfwithSword authored Jan 8, 2025
1 parent 312d7d7 commit 23477ef
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 128 deletions.
57 changes: 33 additions & 24 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ name: Build

on:
workflow_dispatch:
pull_request:
branches:
- main
push:
tags:
- "v*.*.*"
Expand Down Expand Up @@ -45,10 +48,16 @@ jobs:
python -m pip install --upgrade pip pyinstaller
pip install -r requirements.txt
- name: Setup Env Vars
run: |
echo "REF_NAME=${GITHUB_REF_NAME//\//_}" >> $GITHUB_ENV
env:
GITHUB_REF_NAME: ${{ github.ref_name }}

- name: Release Versioning
if: startsWith(github.ref, 'refs/tags/')
run: |
echo "__version__='${{github.ref_name}}'" > src/_version.py
echo "__version__='${{env.REF_NAME}}'" > src/_version.py
- name: Nightly Versioning
if: true && !startsWith(github.ref, 'refs/tags/')
Expand All @@ -58,66 +67,66 @@ jobs:
- name: Build with pyinstaller
if: true && !startsWith(github.ref, 'refs/tags/')
# --noconsole # TODO: update code to log to file if frozen, impl rolling logs in local directory
run: pyinstaller --icon=images/logo.ico --onefile --collect-binaries python312.dll --hidden-import=aiosqlite --hidden-import=pyttsx4.drivers --hidden-import=pyttsx4.drivers.sapi5 --distpath dist/twitchchatdnd/${{ matrix.os }}-${{github.ref_name}}/ --name=twitchchatdnd-nightly src/main.py
run: pyinstaller --icon=images/logo.ico --onefile --collect-binaries python312.dll --hidden-import=aiosqlite --hidden-import=pyttsx4.drivers --hidden-import=pyttsx4.drivers.sapi5 --distpath dist/twitchchatdnd/${{ matrix.os }}-${{env.REF_NAME}}/ --name=twitchchatdnd-nightly src/main.py

- name: Release Build with pyinstaller
if: startsWith(github.ref, 'refs/tags/')
# --noconsole
run: pyinstaller --icon=images/logo.ico --onefile --collect-binaries python312.dll --hidden-import=aiosqlite --hidden-import=pyttsx4.drivers --hidden-import=pyttsx4.drivers.sapi5 --distpath dist/twitchchatdnd/${{ matrix.os }}-${{github.ref_name}}/ --name=twitchchatdnd src/main.py
run: pyinstaller --icon=images/logo.ico --onefile --collect-binaries python312.dll --hidden-import=aiosqlite --hidden-import=pyttsx4.drivers --hidden-import=pyttsx4.drivers.sapi5 --distpath dist/twitchchatdnd/${{ matrix.os }}-${{env.REF_NAME}}/ --name=twitchchatdnd src/main.py

- name: Copy Resources
run: |
mkdir dist/twitchchatdnd/${{ matrix.os }}-${{github.ref_name}}/resources
mkdir dist/twitchchatdnd/${{ matrix.os }}-${{github.ref_name}}/resources/images
mkdir dist/twitchchatdnd/${{ matrix.os }}-${{github.ref_name}}/resources/server
mkdir dist/twitchchatdnd/${{ matrix.os }}-${{github.ref_name}}/resources/server/static
mv images/* dist/twitchchatdnd/${{ matrix.os }}-${{github.ref_name}}/resources/images
mv src/server/static/* dist/twitchchatdnd/${{ matrix.os }}-${{github.ref_name}}/resources/server/static
mkdir dist/twitchchatdnd/${{ matrix.os }}-${{env.REF_NAME}}/resources
mkdir dist/twitchchatdnd/${{ matrix.os }}-${{env.REF_NAME}}/resources/images
mkdir dist/twitchchatdnd/${{ matrix.os }}-${{env.REF_NAME}}/resources/server
mkdir dist/twitchchatdnd/${{ matrix.os }}-${{env.REF_NAME}}/resources/server/static
mv images/* dist/twitchchatdnd/${{ matrix.os }}-${{env.REF_NAME}}/resources/images
mv src/server/static/* dist/twitchchatdnd/${{ matrix.os }}-${{env.REF_NAME}}/resources/server/static
- name: Deploy Artifacts
uses: actions/upload-artifact@v4
if: true && !startsWith(github.ref, 'refs/tags/')
with:
name: twitchchatdnd-${{matrix.os}}-latest
path: dist/twitchchatdnd/${{matrix.os}}-${{github.ref_name}}/
path: dist/twitchchatdnd/${{matrix.os}}-${{env.REF_NAME}}/
if-no-files-found: error
retention-days: 20

- name: Release Rename
if: startsWith(github.ref, 'refs/tags/') && !startsWith(matrix.os, 'windows')
run: |
mkdir twitchchatdnd-${{github.ref_name}}
mv dist/twitchchatdnd/${{matrix.os}}-${{github.ref_name}}/* twitchchatdnd-${{github.ref_name}}/
zip -r twitchchatdnd-${{matrix.os}}-${{github.ref_name}}.zip twitchchatdnd-${{github.ref_name}}
mkdir twitchchatdnd-${{env.REF_NAME}}
mv dist/twitchchatdnd/${{matrix.os}}-${{env.REF_NAME}}/* twitchchatdnd-${{env.REF_NAME}}/
zip -r twitchchatdnd-${{matrix.os}}-${{env.REF_NAME}}.zip twitchchatdnd-${{env.REF_NAME}}
- name: Release Rename - Windows
if: startsWith(github.ref, 'refs/tags/') && startsWith(matrix.os, 'windows')
run: |
mkdir twitchchatdnd-${{github.ref_name}}
mv dist/twitchchatdnd/${{matrix.os}}-${{github.ref_name}}/* twitchchatdnd-${{github.ref_name}}/
7z a twitchchatdnd-${{matrix.os}}-${{github.ref_name}}.zip twitchchatdnd-${{github.ref_name}}
mkdir twitchchatdnd-${{env.REF_NAME}}
mv dist/twitchchatdnd/${{matrix.os}}-${{env.REF_NAME}}/* twitchchatdnd-${{env.REF_NAME}}/
7z a twitchchatdnd-${{matrix.os}}-${{env.REF_NAME}}.zip twitchchatdnd-${{env.REF_NAME}}
- name: Release Artifacts
uses: softprops/action-gh-release@v2
if: startsWith(github.ref, 'refs/tags/')
with:
token: ${{ secrets.TCDND_GITHUB_TOKEN }}
files: twitchchatdnd-${{matrix.os}}-${{github.ref_name}}.zip
files: twitchchatdnd-${{matrix.os}}-${{env.REF_NAME}}.zip

- name: Nightly Release Rename
if: true && !startsWith(github.ref, 'refs/tags/') && !startsWith(matrix.os, 'windows')
run: |
mkdir twitchchatdnd-${{github.ref_name}}
mv dist/twitchchatdnd/${{matrix.os}}-${{github.ref_name}}/* twitchchatdnd-${{github.ref_name}}/
zip -r twitchchatdnd-${{matrix.os}}-${{github.ref_name}}.zip twitchchatdnd-${{github.ref_name}}
mkdir twitchchatdnd-${{env.REF_NAME}}
mv dist/twitchchatdnd/${{matrix.os}}-${{env.REF_NAME}}/* twitchchatdnd-${{env.REF_NAME}}/
zip -r twitchchatdnd-${{matrix.os}}-${{env.REF_NAME}}.zip twitchchatdnd-${{env.REF_NAME}}
- name: Nightly Rename - Windows
if: true && !startsWith(github.ref, 'refs/tags/') && startsWith(matrix.os, 'windows')
run: |
mkdir twitchchatdnd-${{github.ref_name}}
mv dist/twitchchatdnd/${{matrix.os}}-${{github.ref_name}}/* twitchchatdnd-${{github.ref_name}}/
7z a twitchchatdnd-${{matrix.os}}-${{github.ref_name}}.zip twitchchatdnd-${{github.ref_name}}
mkdir twitchchatdnd-${{env.REF_NAME}}
mv dist/twitchchatdnd/${{matrix.os}}-${{env.REF_NAME}}/* twitchchatdnd-${{env.REF_NAME}}/
7z a twitchchatdnd-${{matrix.os}}-${{env.REF_NAME}}.zip twitchchatdnd-${{env.REF_NAME}}
- name: Release nightly
uses: softprops/action-gh-release@v2
Expand All @@ -127,5 +136,5 @@ jobs:
prerelease: true
name: nightly
tag_name: nightly
files: twitchchatdnd-${{matrix.os}}-${{github.ref_name}}.zip
files: twitchchatdnd-${{matrix.os}}-${{env.REF_NAME}}.zip
fail_on_unmatched_files: true
15 changes: 4 additions & 11 deletions src/helpers/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import configparser
import base64

# ID is fine to ship
_client_id = base64.b64decode("dXp4NXFiOXNzZXl0dGtvZXF5cXdydmthOGdic3Br").decode('utf-8')

class TCDNDConfig(configparser.ConfigParser):

Expand Down Expand Up @@ -49,12 +52,6 @@ def setup(self, path: str):
if not self.has_option(section="TWITCH", option="channel"):
needs_init = True
self.set(section="TWITCH", option="channel", value="")
if not self.has_option(section="TWITCH", option="client_id"):
needs_init = True
self.set(section="TWITCH", option="client_id", value="")
if not self.has_option(section="TWITCH", option="client_secret"):
needs_init = True
self.set(section="TWITCH", option="client_secret", value="")

if not self.has_section("DND"):
needs_init = True
Expand All @@ -68,11 +65,7 @@ def setup(self, path: str):

@property
def twitch_auth(self) -> tuple[str, str]:
client_id = self.get(section='TWITCH', option='client_id', fallback='')
client_secret = self.get(section='TWITCH', option='client_secret', fallback='')
if client_id == '' or client_secret == '':
return None, None
return client_id.strip(), client_secret.strip()
return _client_id.strip()

@property
def cache_enabled(self) -> bool:
Expand Down
9 changes: 2 additions & 7 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
async def run_twitch():

async def try_setup():
while not all(config.twitch_auth):
while not config.twitch_auth:
await asyncio.sleep(5)
logger.info("Starting Twitch Client...")

Expand All @@ -51,13 +51,8 @@ async def try_setup():
if twitch_utils.twitch:
return True
except Exception as e:
logger.error(f"Invalid Twitch Client Id or Client Secret or other Twitch connection issue")
logger.error(f"Invalid Twitch Connection")
logger.error(e)
# only clear on twitch errors
if type(e) == TwitchAuthorizationException:
config.set(section="TWITCH", option="client_id", value='')
config.set(section="TWITCH", option="client_secret", value='')
config.write_updates()
return False

success = False
Expand Down
5 changes: 3 additions & 2 deletions src/twitch/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,11 @@ async def start(self):
self.twitch = None
SCOPES = [AuthScope.CHAT_READ, AuthScope.CHAT_EDIT] # TODO may need more as time goes on
try:
self.twitch = await Twitch(*self.config.twitch_auth)
self.twitch = await Twitch(app_id=self.config.twitch_auth, authenticate_app=False)
helper = UserAuthenticationStorageHelper(self.twitch, SCOPES, auth_generator_func=self._token_gen)
await helper.bind()
except:
except Exception as e:
logger.error(e)
twitchutils_twitch_on_connect_event.trigger([False, None])
raise
logger.info("Twitch connected")
Expand Down
109 changes: 25 additions & 84 deletions src/ui/tabs/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,64 +22,23 @@ def __init__(self, parent, config: Config, twitch_utils: TwitchUtils):
row=0
######### Twitch ##########
column=0
label = ctk.CTkLabel(self.parent, text="Twitch", font=header_font)
label = ctk.CTkLabel(self.parent, text="Twitch Bot", font=header_font)
label.grid(row=row, column=column, padx=10, pady=(30,2), sticky="ew")
column+=1
self.t_con_label = ctk.CTkLabel(self.parent, text="Disconnected", text_color="red")
self.t_con_label = ctk.CTkLabel(self.parent, text="Twitch Disconnected", text_color="red")
self.t_con_label.grid(row=row, column=column, padx=10, pady=(30,2))
column+=1
self.chat_con_label = ctk.CTkLabel(self.parent, text="Chat Disconnected", text_color="red")
self.chat_con_label.grid(row=row, column=column, padx=10, pady=(30,2))
chat_bot_on_connect.addListener(self._update_bot_connection)
column=0
row+=1

button = ctk.CTkButton(self.parent,height=30, text="Save", command=self._update_twitch_auth)
button = ctk.CTkButton(self.parent,height=30, text="Save", command=self._update_bot_settings)
button.grid(row=row, column=column, padx=10, pady=(20,10))
column+=1
chan_label = ctk.CTkLabel(self.parent, text="Channel")
id_label = ctk.CTkLabel(self.parent, text="Client Id")
secret_label = ctk.CTkLabel(self.parent, text="Client Secret")
chan_label.grid(row=row, column=column, padx=(10,10), pady=(10,2))
column+=1
id_label.grid(row=row, column=column, padx=(10, 10), pady=(10,2))
column+=1
secret_label.grid(row=row, column=column, padx=(10, 10), pady=(10,2))
column+=1

row+=1
column=1
self.channel_var = ctk.StringVar(value=self.config.get(section="TWITCH", option="channel", fallback=""))
twitch_channel = ctk.CTkEntry(self.parent, width=180, height=30, border_width=1, fg_color="white", placeholder_text="Channel", text_color="black", textvariable=self.channel_var)
twitch_channel.configure(justify="center")
self.clientid_var = ctk.StringVar(value=self.config.get(section="TWITCH", option="client_id", fallback=""))
twitch_client_id = ctk.CTkEntry(self.parent, width=160, height=30, border_width=1, fg_color="white", placeholder_text="Client Id", text_color="black", textvariable=self.clientid_var)
self.clientsecret_var = ctk.StringVar(value=self.config.get(section="TWITCH", option="client_secret", fallback=""))
twitch_client_secret = ctk.CTkEntry(self.parent, width=160, height=30, border_width=1, fg_color="white", placeholder_text="Client Secret", text_color="black", show="*", textvariable=self.clientsecret_var)

twitch_channel.grid(row=row, column=column, padx=(20,20), pady=(2, 20))
column+=1
twitch_client_id.grid(row=row, column=column, padx=(20,20), pady=(2, 20))
column+=1
twitch_client_secret.grid(row=row, column=column, padx=(20,20), pady=(2, 20))


twitchutils_twitch_on_connect_event.addListener(self._update_twitch_connect)
chat_on_channel_fetch.addListener(self._update_twitch_channel)

########################


######### BOT ##########
row += 1
column = 0
label_bot = ctk.CTkLabel(self.parent, text="Bot", font=header_font)
label_bot.grid(row=row, column=column, padx=10, pady=(40,10), sticky="ew")
column+=1
self.chat_con_label = ctk.CTkLabel(self.parent, text="Disconnected", text_color="red")
self.chat_con_label.grid(row=row, column=column, padx=10, pady=(40,2))
chat_bot_on_connect.addListener(self._update_bot_connection)
column=0
row+=1
bot_button = ctk.CTkButton(self.parent,height=30, text="Save", command=self._update_bot_settings)
bot_button.grid(row=row, column=column, padx=10, pady=(20,10))

column+=1
prefix_label = ctk.CTkLabel(self.parent, text="Command Prefix")
prefix_label.grid(row=row, column=column, padx=(10,10), pady=(10,2))
Expand All @@ -92,8 +51,14 @@ def __init__(self, parent, config: Config, twitch_utils: TwitchUtils):

row+=1
column=1
self.channel_var = ctk.StringVar(value=self.config.get(section="TWITCH", option="channel", fallback=""))
twitch_channel = ctk.CTkEntry(self.parent, width=180, height=30, border_width=1, fg_color="white", placeholder_text="Channel", text_color="black", textvariable=self.channel_var)
twitch_channel.configure(justify="center")

twitch_channel.grid(row=row, column=column, padx=(20,20), pady=(2, 20))
column+=1
self.prefix_var = ctk.StringVar(value=self.config.get(section="BOT", option="prefix", fallback='!').strip()[0])
prefix_options = ctk.CTkSegmentedButton(self.parent, values=['!', '~', '+', '&'], variable=self.prefix_var)#command=self._update_prefix)
prefix_options = ctk.CTkSegmentedButton(self.parent, values=['!', '~', '+', '&'], variable=self.prefix_var)
prefix_options.grid(row=row, column=column, padx=(20,20), pady=(2, 20))
column += 1
self.join_cmd_var = ctk.StringVar(value=self.config.get(section="BOT", option="join_command", fallback=''))
Expand All @@ -106,6 +71,8 @@ def __init__(self, parent, config: Config, twitch_utils: TwitchUtils):
speak_cmd_entry.grid(row=row, column=column, padx=(20,20), pady=(2, 20))
speak_cmd_entry.configure(justify="center")

twitchutils_twitch_on_connect_event.addListener(self._update_twitch_connect)

########################

####### Web Srv ########
Expand All @@ -127,51 +94,25 @@ def __init__(self, parent, config: Config, twitch_utils: TwitchUtils):


def _update_bot_settings(self):
self.chat_con_label.configure(text="Chat Connecting...", text_color="yellow")
self.config.set(section="BOT", option="prefix", value=str(self.prefix_var.get()))
self.config.set(section="BOT", option="speak_command", value=self.speak_cmd_var.get().strip())
self.config.set(section="BOT", option="join_command", value=self.join_cmd_var.get().strip())
self.config.set(section="TWITCH", option="channel", value=self.channel_var.get())
self.config.write_updates()
ui_settings_bot_settings_update_event.trigger()


def _update_twitch_connect(self, status: bool, twitchutils = None):
if status:
self.t_con_label.configure(text="Connected", text_color="green")
else:
if self.clientid_var.get():
self.clientid_var.set("")
if self.clientsecret_var.get():
self.clientsecret_var.set("")
self.t_con_label.configure(text="Disconnected", text_color="red")
self.parent.focus()
ui_settings_twitch_channel_update_event.trigger([True, self.twitch_utils, 5])


def _update_twitch_channel(self, status: bool):
def _update_bot_connection(self, status: bool):
if status:
self.t_con_label.configure(text="Connected", text_color="green")
self.chat_con_label.configure(text="Chat Connected", text_color="green")
else:
if self.channel_var.get():
self.channel_var.set("")
self.t_con_label.configure(text="Disconnected", text_color="red")
self.chat_con_label.configure(text="Chat Disconnected", text_color="red")
self.parent.focus()


def _update_bot_connection(self, status: bool):
def _update_twitch_connect(self, status: bool, twitchutils = None):
if status:
self.chat_con_label.configure(text="Connected", text_color="green")
self.t_con_label.configure(text="Twitch Connected", text_color="green")
else:
self.chat_con_label.configure(text="Disconnected", text_color="red")
self.t_con_label.configure(text="Twitch Disconnected", text_color="red")
self.parent.focus()


def _update_twitch_auth(self):
if not self.config.has_section("TWITCH"):
self.config.add_section("TWITCH")
self.config.set(section="TWITCH", option="client_id", value=self.clientid_var.get())
self.config.set(section="TWITCH", option="client_secret", value=self.clientsecret_var.get())
self.config.set(section="TWITCH", option="channel", value=self.channel_var.get())
self.t_con_label.configure(text="Connecting...", text_color="yellow")
self.chat_con_label.configure(text="Connecting...", text_color="yellow")
self.config.write_updates()
ui_settings_twitch_auth_update_event.trigger()
ui_settings_twitch_channel_update_event.trigger([True, self.twitch_utils, 5])

0 comments on commit 23477ef

Please sign in to comment.