Initial commit with translated description
This commit is contained in:
170
scripts/briefing.py
Normal file
170
scripts/briefing.py
Normal file
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Briefing Generator - Main entry point for market briefings.
|
||||
Generates and optionally sends to WhatsApp group.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
from utils import ensure_venv
|
||||
|
||||
SCRIPT_DIR = Path(__file__).parent
|
||||
|
||||
ensure_venv()
|
||||
|
||||
|
||||
def send_to_whatsapp(message: str, group_name: str | None = None):
|
||||
"""Send message to WhatsApp group via openclaw message tool."""
|
||||
if not group_name:
|
||||
group_name = os.environ.get('FINANCE_NEWS_TARGET', '')
|
||||
if not group_name:
|
||||
print("❌ No target specified. Set FINANCE_NEWS_TARGET env var or use --group", file=sys.stderr)
|
||||
return False
|
||||
# Use openclaw message tool
|
||||
try:
|
||||
result = subprocess.run(
|
||||
[
|
||||
'openclaw', 'message', 'send',
|
||||
'--channel', 'whatsapp',
|
||||
'--target', group_name,
|
||||
'--message', message
|
||||
],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=30
|
||||
)
|
||||
|
||||
if result.returncode == 0:
|
||||
print(f"✅ Sent to WhatsApp group: {group_name}", file=sys.stderr)
|
||||
return True
|
||||
else:
|
||||
print(f"⚠️ WhatsApp send failed: {result.stderr}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ WhatsApp error: {e}", file=sys.stderr)
|
||||
return False
|
||||
|
||||
|
||||
def generate_and_send(args):
|
||||
"""Generate briefing and optionally send to WhatsApp."""
|
||||
|
||||
# Determine briefing type based on current time or args
|
||||
if args.time:
|
||||
briefing_time = args.time
|
||||
else:
|
||||
hour = datetime.now().hour
|
||||
briefing_time = 'morning' if hour < 12 else 'evening'
|
||||
|
||||
# Generate the briefing
|
||||
cmd = [
|
||||
sys.executable, SCRIPT_DIR / 'summarize.py',
|
||||
'--time', briefing_time,
|
||||
'--style', args.style,
|
||||
'--lang', args.lang
|
||||
]
|
||||
|
||||
if args.deadline is not None:
|
||||
cmd.extend(['--deadline', str(args.deadline)])
|
||||
|
||||
if args.fast:
|
||||
cmd.append('--fast')
|
||||
|
||||
if args.llm:
|
||||
cmd.append('--llm')
|
||||
cmd.extend(['--model', args.model])
|
||||
|
||||
if args.debug:
|
||||
cmd.append('--debug')
|
||||
|
||||
# Always use JSON for internal processing to handle splits
|
||||
cmd.append('--json')
|
||||
|
||||
print(f"📊 Generating {briefing_time} briefing...", file=sys.stderr)
|
||||
|
||||
timeout = args.deadline if args.deadline is not None else 300
|
||||
timeout = max(1, int(timeout))
|
||||
if args.deadline is not None:
|
||||
timeout = timeout + 5
|
||||
result = subprocess.run(
|
||||
cmd,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
stdin=subprocess.DEVNULL,
|
||||
timeout=timeout
|
||||
)
|
||||
|
||||
if result.returncode != 0:
|
||||
print(f"❌ Briefing generation failed: {result.stderr}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
try:
|
||||
data = json.loads(result.stdout.strip())
|
||||
except json.JSONDecodeError:
|
||||
# Fallback if not JSON (shouldn't happen with --json)
|
||||
print(f"⚠️ Failed to parse briefing JSON", file=sys.stderr)
|
||||
print(result.stdout)
|
||||
return result.stdout
|
||||
|
||||
# Output handling
|
||||
if args.json:
|
||||
print(json.dumps(data, indent=2))
|
||||
else:
|
||||
# Print for humans
|
||||
if data.get('macro_message'):
|
||||
print(data['macro_message'])
|
||||
if data.get('portfolio_message'):
|
||||
print("\n" + "="*20 + "\n")
|
||||
print(data['portfolio_message'])
|
||||
|
||||
# Send to WhatsApp if requested
|
||||
if args.send and args.group:
|
||||
# Message 1: Macro
|
||||
macro_msg = data.get('macro_message') or data.get('summary', '')
|
||||
if macro_msg:
|
||||
send_to_whatsapp(macro_msg, args.group)
|
||||
|
||||
# Message 2: Portfolio (if exists)
|
||||
portfolio_msg = data.get('portfolio_message')
|
||||
if portfolio_msg:
|
||||
send_to_whatsapp(portfolio_msg, args.group)
|
||||
|
||||
return data.get('macro_message', '')
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description='Briefing Generator')
|
||||
parser.add_argument('--time', choices=['morning', 'evening'],
|
||||
help='Briefing type (auto-detected if not specified)')
|
||||
parser.add_argument('--style', choices=['briefing', 'analysis', 'headlines'],
|
||||
default='briefing', help='Summary style')
|
||||
parser.add_argument('--lang', choices=['en', 'de'], default='en',
|
||||
help='Output language')
|
||||
parser.add_argument('--send', action='store_true',
|
||||
help='Send to WhatsApp group')
|
||||
parser.add_argument('--group', default=os.environ.get('FINANCE_NEWS_TARGET', ''),
|
||||
help='WhatsApp group name or JID (default: FINANCE_NEWS_TARGET env var)')
|
||||
parser.add_argument('--json', action='store_true',
|
||||
help='Output as JSON')
|
||||
parser.add_argument('--deadline', type=int, default=None,
|
||||
help='Overall deadline in seconds')
|
||||
parser.add_argument('--llm', action='store_true', help='Use LLM summary')
|
||||
parser.add_argument('--model', choices=['claude', 'minimax', 'gemini'],
|
||||
default='claude', help='LLM model (only with --llm)')
|
||||
parser.add_argument('--fast', action='store_true',
|
||||
help='Use fast mode (shorter timeouts, fewer items)')
|
||||
parser.add_argument('--debug', action='store_true',
|
||||
help='Write debug log with sources')
|
||||
|
||||
args = parser.parse_args()
|
||||
generate_and_send(args)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user