Spaces:
Sleeping
Sleeping
| # google_docs_config.py - Simplified Google Docs Integration | |
| import os | |
| import json | |
| import tempfile | |
| from typing import Optional, Tuple | |
| import streamlit as st | |
| try: | |
| from googleapiclient.discovery import build | |
| from google.auth.transport.requests import Request | |
| from google.oauth2.credentials import Credentials | |
| from google_auth_oauthlib.flow import InstalledAppFlow | |
| GOOGLE_AVAILABLE = True | |
| except ImportError: | |
| GOOGLE_AVAILABLE = False | |
| class GoogleDocsManager: | |
| """Simplified Google Docs manager for direct export""" | |
| def __init__(self): | |
| self.SCOPES = ['https://www.googleapis.com/auth/documents'] | |
| self.creds = None | |
| self.service = None | |
| def authenticate(self) -> bool: | |
| """Authenticate with Google Docs API""" | |
| if not GOOGLE_AVAILABLE: | |
| return False | |
| try: | |
| # Check if we have stored credentials | |
| if os.path.exists('token.json'): | |
| self.creds = Credentials.from_authorized_user_file('token.json', self.SCOPES) | |
| # If there are no (valid) credentials available, let the user log in | |
| if not self.creds or not self.creds.valid: | |
| if self.creds and self.creds.expired and self.creds.refresh_token: | |
| self.creds.refresh(Request()) | |
| else: | |
| # Create credentials.json if it doesn't exist | |
| self._create_credentials_file() | |
| if os.path.exists('credentials.json'): | |
| # Use web flow for Streamlit app | |
| flow = InstalledAppFlow.from_client_secrets_file('credentials.json', self.SCOPES) | |
| # Use a different port to avoid conflict with Streamlit | |
| self.creds = flow.run_local_server(port=8502, open_browser=True) | |
| else: | |
| return False | |
| # Save the credentials for the next run | |
| with open('token.json', 'w') as token: | |
| token.write(self.creds.to_json()) | |
| self.service = build('docs', 'v1', credentials=self.creds) | |
| return True | |
| except Exception as e: | |
| st.error(f"Google authentication error: {str(e)}") | |
| return False | |
| def _create_credentials_file(self): | |
| """Create a basic credentials.json file template""" | |
| credentials_template = { | |
| "installed": { | |
| "client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com", | |
| "project_id": "your-project-id", | |
| "auth_uri": "https://accounts.google.com/o/oauth2/auth", | |
| "token_uri": "https://oauth2.googleapis.com/token", | |
| "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", | |
| "client_secret": "YOUR_CLIENT_SECRET", | |
| "redirect_uris": ["http://localhost"] | |
| } | |
| } | |
| if not os.path.exists('credentials.json'): | |
| with open('credentials.json', 'w') as f: | |
| json.dump(credentials_template, f, indent=2) | |
| st.warning(""" | |
| 📝 Google Docs Setup Required: | |
| 1. Go to https://console.cloud.google.com/ | |
| 2. Create a new project or select existing one | |
| 3. Enable Google Docs API | |
| 4. Create credentials (OAuth 2.0 Client ID) | |
| 5. Download the credentials.json file | |
| 6. Replace the generated credentials.json with your downloaded file | |
| 7. Restart the application | |
| """) | |
| def create_document(self, title: str, content: str) -> Tuple[Optional[str], Optional[str]]: | |
| """Create a Google Docs document with content""" | |
| if not self.service: | |
| if not self.authenticate(): | |
| return None, "Failed to authenticate with Google Docs" | |
| try: | |
| # Create document | |
| document = {'title': title} | |
| doc = self.service.documents().create(body=document).execute() | |
| document_id = doc.get('documentId') | |
| # Add content if provided | |
| if content.strip(): | |
| requests = [ | |
| { | |
| 'insertText': { | |
| 'location': {'index': 1}, | |
| 'text': content | |
| } | |
| } | |
| ] | |
| self.service.documents().batchUpdate( | |
| documentId=document_id, | |
| body={'requests': requests} | |
| ).execute() | |
| # Return shareable URL | |
| doc_url = f"https://docs.google.com/document/d/{document_id}/edit" | |
| return doc_url, None | |
| except Exception as e: | |
| return None, f"Error creating Google Docs document: {str(e)}" | |
| def logout(self) -> bool: | |
| """Logout from Google account by removing stored credentials""" | |
| try: | |
| # Remove token file | |
| if os.path.exists('token.json'): | |
| os.remove('token.json') | |
| # Clear current credentials | |
| self.creds = None | |
| self.service = None | |
| return True | |
| except Exception as e: | |
| print(f"Error during logout: {e}") | |
| return False | |
| def is_authenticated(self) -> bool: | |
| """Check if user is currently authenticated""" | |
| return self.creds is not None and self.creds.valid | |
| def get_current_user_email(self) -> Optional[str]: | |
| """Get the email of the currently authenticated user""" | |
| if self.is_authenticated(): | |
| try: | |
| # This would require additional API call to get user info | |
| # For now, we'll return a placeholder | |
| return "authenticated_user@gmail.com" | |
| except Exception: | |
| return None | |
| return None | |
| def export_broadcast_to_docs(self, segments, ui_language='ar') -> Tuple[Optional[str], Optional[str]]: | |
| """Export broadcast segments directly to Google Docs""" | |
| # Create title | |
| from datetime import datetime | |
| timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S') | |
| title = f"محاضرة - تصدير البرودكاست - {timestamp}" if ui_language == 'ar' else f"Lecture - Broadcast Export - {timestamp}" | |
| # Prepare content | |
| content_lines = [] | |
| content_lines.append(f"{'تصدير البرودكاست' if ui_language == 'ar' else 'Broadcast Export'}") | |
| content_lines.append(f"{'التاريخ والوقت' if ui_language == 'ar' else 'Date & Time'}: {timestamp}") | |
| content_lines.append("=" * 50) | |
| content_lines.append("") | |
| if segments: | |
| content_lines.append(f"{'المقاطع النصية' if ui_language == 'ar' else 'Text Segments'}:") | |
| content_lines.append("-" * 30) | |
| for segment in segments: | |
| start_time = segment.get('start_ms', 0) / 1000 | |
| end_time = segment.get('end_ms', 0) / 1000 | |
| content_lines.append(f"[{start_time:.2f}s → {end_time:.2f}s]") | |
| # Original text | |
| original_text = segment.get('text', '') | |
| if original_text: | |
| content_lines.append(f"{'النص الأصلي' if ui_language == 'ar' else 'Original'}: {original_text}") | |
| # Translation | |
| translations = segment.get('translations', {}) | |
| for lang_code, translation in translations.items(): | |
| if translation: | |
| content_lines.append(f"{'الترجمة' if ui_language == 'ar' else 'Translation'} ({lang_code.upper()}): {translation}") | |
| # Model used | |
| model_used = segment.get('transcription_model') | |
| if model_used: | |
| content_lines.append(f"{'النموذج المستخدم' if ui_language == 'ar' else 'Model Used'}: {model_used}") | |
| content_lines.append("") | |
| else: | |
| content_lines.append(f"{'لا توجد مقاطع نصية متاحة' if ui_language == 'ar' else 'No text segments available'}") | |
| content = "\n".join(content_lines) | |
| # Create document | |
| return self.create_document(title, content) | |
| # Global instance | |
| google_docs_manager = GoogleDocsManager() |