Shirochi commited on
Commit
afe316a
Β·
verified Β·
1 Parent(s): 9c28f9d

Upload app.py

Browse files
Files changed (1) hide show
  1. app.py +68 -19
app.py CHANGED
@@ -3367,14 +3367,25 @@ class GlossarionWeb:
3367
 
3368
  # AuthGPT login button (visible for authgpt/* models)
3369
  _initial_model = self.get_config_value('model', 'authgpt/gpt-5.2').lower()
 
 
3370
  authgpt_login_btn = gr.Button(
3371
- "πŸ” ChatGPT Login",
3372
  variant="secondary",
3373
- visible=_initial_model.startswith('authgpt/')
 
 
 
 
 
 
 
 
 
3374
  )
3375
  authgpt_login_status = gr.Textbox(
3376
  label="", interactive=False, visible=False,
3377
- max_lines=1
3378
  )
3379
 
3380
  # Use all profiles without filtering
@@ -3980,18 +3991,20 @@ class GlossarionWeb:
3980
 
3981
  # --- Model change handlers: toggle API key & AuthGPT login ---
3982
  def _on_model_change(model):
3983
- """Return visibility updates for API key and AuthGPT login button."""
3984
  hide_key = _model_needs_no_api_key(model or '')
3985
  is_authgpt = (model or '').lower().startswith('authgpt/')
 
3986
  return (
3987
- gr.update(visible=not hide_key), # api_key
3988
- gr.update(visible=is_authgpt), # authgpt_login_btn
 
3989
  )
3990
 
3991
  epub_model.change(
3992
  fn=_on_model_change,
3993
  inputs=[epub_model],
3994
- outputs=[epub_api_key, authgpt_login_btn]
3995
  )
3996
  manga_model.change(
3997
  fn=lambda m: gr.update(visible=not _model_needs_no_api_key(m or '')),
@@ -4000,32 +4013,68 @@ class GlossarionWeb:
4000
  )
4001
 
4002
  # --- AuthGPT Login handler ---
4003
- def _authgpt_login():
4004
- """Run OAuth flow for ChatGPT subscription login."""
 
 
 
 
4005
  try:
4006
- from authgpt_auth import get_default_store, run_oauth_flow
 
4007
  store = get_default_store()
4008
 
 
 
4009
  # If already logged in, show status
4010
- if store.has_tokens:
4011
  info = store.account_info
4012
  email = info.get('email', '')
4013
  plan = info.get('plan_type', '')
4014
  return gr.update(value=f"βœ… Already logged in ({email or plan or 'active'})", visible=True)
4015
 
4016
- # Run OAuth flow (opens browser)
4017
- tokens = run_oauth_flow()
4018
- store.save_tokens(tokens)
4019
- info = store.account_info
4020
- email = info.get('email', '')
4021
- plan = info.get('plan_type', '')
4022
- return gr.update(value=f"βœ… Logged in ({email or plan or 'success'})", visible=True)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4023
  except Exception as e:
4024
  return gr.update(value=f"❌ Login failed: {e}", visible=True)
4025
 
4026
  authgpt_login_btn.click(
4027
  fn=_authgpt_login,
4028
- inputs=[],
4029
  outputs=[authgpt_login_status],
4030
  concurrency_limit=None # OAuth flow blocks for up to 300s waiting for browser callback
4031
  )
 
3367
 
3368
  # AuthGPT login button (visible for authgpt/* models)
3369
  _initial_model = self.get_config_value('model', 'authgpt/gpt-5.2').lower()
3370
+ _is_hf_spaces = os.getenv('SPACE_ID') is not None or os.getenv('HF_SPACES') == 'true'
3371
+ _show_authgpt = _initial_model.startswith('authgpt/')
3372
  authgpt_login_btn = gr.Button(
3373
+ "πŸ” ChatGPT Login" if not _is_hf_spaces else "πŸ” Save Token",
3374
  variant="secondary",
3375
+ visible=_show_authgpt
3376
+ )
3377
+ # On HF Spaces, show a textbox for users to paste their refresh token
3378
+ authgpt_token_input = gr.Textbox(
3379
+ label="πŸ”‘ AuthGPT Refresh Token",
3380
+ type="password",
3381
+ placeholder="Paste refresh_token from ~/.glossarion/authgpt_tokens.json",
3382
+ visible=_is_hf_spaces and _show_authgpt,
3383
+ info="Browser login unavailable on HF Spaces. Paste your refresh token here.",
3384
+ interactive=True
3385
  )
3386
  authgpt_login_status = gr.Textbox(
3387
  label="", interactive=False, visible=False,
3388
+ max_lines=2
3389
  )
3390
 
3391
  # Use all profiles without filtering
 
3991
 
3992
  # --- Model change handlers: toggle API key & AuthGPT login ---
3993
  def _on_model_change(model):
3994
+ """Return visibility updates for API key, AuthGPT login button, and token input."""
3995
  hide_key = _model_needs_no_api_key(model or '')
3996
  is_authgpt = (model or '').lower().startswith('authgpt/')
3997
+ _hf = os.getenv('SPACE_ID') is not None or os.getenv('HF_SPACES') == 'true'
3998
  return (
3999
+ gr.update(visible=not hide_key), # api_key
4000
+ gr.update(visible=is_authgpt), # authgpt_login_btn
4001
+ gr.update(visible=is_authgpt and _hf), # authgpt_token_input
4002
  )
4003
 
4004
  epub_model.change(
4005
  fn=_on_model_change,
4006
  inputs=[epub_model],
4007
+ outputs=[epub_api_key, authgpt_login_btn, authgpt_token_input]
4008
  )
4009
  manga_model.change(
4010
  fn=lambda m: gr.update(visible=not _model_needs_no_api_key(m or '')),
 
4013
  )
4014
 
4015
  # --- AuthGPT Login handler ---
4016
+ def _authgpt_login(pasted_token):
4017
+ """Run OAuth flow for ChatGPT subscription login.
4018
+
4019
+ On Hugging Face Spaces (headless), accepts a pasted refresh token
4020
+ instead of opening a browser for the OAuth flow.
4021
+ """
4022
  try:
4023
+ import time
4024
+ from authgpt_auth import get_default_store, run_oauth_flow, refresh_access_token
4025
  store = get_default_store()
4026
 
4027
+ _hf = os.getenv('SPACE_ID') is not None or os.getenv('HF_SPACES') == 'true'
4028
+
4029
  # If already logged in, show status
4030
+ if store.has_tokens and not pasted_token:
4031
  info = store.account_info
4032
  email = info.get('email', '')
4033
  plan = info.get('plan_type', '')
4034
  return gr.update(value=f"βœ… Already logged in ({email or plan or 'active'})", visible=True)
4035
 
4036
+ if _hf:
4037
+ # --- HF Spaces: use pasted token ---
4038
+ token_str = (pasted_token or '').strip()
4039
+ if not token_str:
4040
+ return gr.update(
4041
+ value="❌ Paste your refresh_token from ~/.glossarion/authgpt_tokens.json above, then click Save Token.",
4042
+ visible=True
4043
+ )
4044
+
4045
+ # Try to use the pasted value as a refresh token
4046
+ try:
4047
+ refreshed = refresh_access_token(token_str)
4048
+ store.save_tokens(refreshed)
4049
+ info = store.account_info
4050
+ email = info.get('email', '')
4051
+ plan = info.get('plan_type', '')
4052
+ return gr.update(value=f"βœ… Logged in via token ({email or plan or 'success'})", visible=True)
4053
+ except Exception as ref_exc:
4054
+ # Maybe it's a raw access token instead?
4055
+ manual_tokens = {
4056
+ "access_token": token_str,
4057
+ "expires_at": time.time() + 3600,
4058
+ }
4059
+ store.save_tokens(manual_tokens)
4060
+ return gr.update(
4061
+ value=f"⚠️ Saved as access token (refresh failed: {ref_exc}). May expire in ~1h.",
4062
+ visible=True
4063
+ )
4064
+ else:
4065
+ # --- Local/desktop: run browser OAuth flow ---
4066
+ tokens = run_oauth_flow()
4067
+ store.save_tokens(tokens)
4068
+ info = store.account_info
4069
+ email = info.get('email', '')
4070
+ plan = info.get('plan_type', '')
4071
+ return gr.update(value=f"βœ… Logged in ({email or plan or 'success'})", visible=True)
4072
  except Exception as e:
4073
  return gr.update(value=f"❌ Login failed: {e}", visible=True)
4074
 
4075
  authgpt_login_btn.click(
4076
  fn=_authgpt_login,
4077
+ inputs=[authgpt_token_input],
4078
  outputs=[authgpt_login_status],
4079
  concurrency_limit=None # OAuth flow blocks for up to 300s waiting for browser callback
4080
  )