#!/usr/bin/env python3 """ SugarCRM 6.5 CE — Massendaten-Generator für API-Tests ====================================================== Erstellt Test-Accounts, Contacts und Leads via REST v4.1 API. Nützlich für Lasttests und Datenmigration-Tests. Usage: python3 test_seed.py # 10 Accounts + 10 Contacts python3 test_seed.py --count 50 # 50 von jedem python3 test_seed.py --clean # Alle Test-Daten löschen """ import http.client import json import hashlib import urllib.parse import sys import os import time import argparse from datetime import datetime BASE_HOST = os.environ.get("SUGARCRM_HOST", "localhost") BASE_PORT = os.environ.get("SUGARCRM_PORT", "2080") ENDPOINT = "/service/v4_1/rest.php" BASE_URL = f"{BASE_HOST}:{BASE_PORT}" USER = os.environ.get("SUGARCRM_USER", "admin") PASSWORD = os.environ.get("SUGARCRM_PASSWORD", "admin123") PWD_HASH = hashlib.md5(PASSWORD.encode()).hexdigest() COMPANIES = ["ACME Corp", "Globex Inc", "Initech", "Umbrella Corp", "Stark Industries", "Wayne Enterprises", "Oscorp", "Massive Dynamic", "Weyland-Yutani", "Cyberdyne", "Hooli", "Pied Piper", "Dunder Mifflin", "Sterling Cooper", "Los Pollos Hermanos", "Bluth Company", "Soylent Corp", "Tyrell Corp", "Aperture Science", "Black Mesa"] FIRST_NAMES = ["Max", "Erika", "Klaus", "Sabine", "Thomas", "Julia", "Michael", "Anna", "Peter", "Laura", "Andreas", "Maria", "Stefan", "Nicole", "Markus"] LAST_NAMES = ["Müller", "Schmidt", "Schneider", "Fischer", "Weber", "Meyer", "Wagner", "Becker", "Hoffmann", "Schäfer", "Koch", "Bauer", "Richter", "Klein", "Wolf"] INDUSTRIES = ["Technology", "Healthcare", "Finance", "Manufacturing", "Retail", "Energy", "Education", "Media", "Transportation", "Real Estate"] def call_api(method, rest_data): conn = http.client.HTTPConnection(BASE_URL, timeout=30) body = urllib.parse.urlencode({ "method": method, "input_type": "JSON", "response_type": "JSON", "rest_data": json.dumps(rest_data) }) conn.request("POST", ENDPOINT, body, {"Content-Type": "application/x-www-form-urlencoded"}) resp = conn.getresponse() if resp.status == 302: return {"_error": "Redirect"} data = json.loads(resp.read().decode()) conn.close() return data def login(): print("🔑 Login...", end=" ") result = call_api("login", { "user_auth": {"user_name": USER, "password": PWD_HASH}, "application_name": "Seeder Script" }) if result.get("id"): print("✅") return result["id"] print(f"❌ {result.get('description', 'Unknown error')}") sys.exit(1) def create_accounts(session, count): print(f"\n🏢 Erstelle {count} Accounts...") created = 0 for i in range(count): name = f"{COMPANIES[i % len(COMPANIES)]} (Seed {i+1})" result = call_api("set_entry", { "session": session, "module_name": "Accounts", "name_value_list": { "name": {"name": "name", "value": name}, "account_type": {"name": "account_type", "value": "Customer"}, "industry": {"name": "industry", "value": INDUSTRIES[i % len(INDUSTRIES)]}, "phone_office": {"name": "phone_office", "value": f"+49 30 {1000000+i}"}, "description": {"name": "description", "value": f"API Seeder {datetime.now().isoformat()}"}, } }) if result.get("id"): created += 1 if (i+1) % 20 == 0: print(f" ... {i+1}/{count}") time.sleep(0.1) # Rate limiting print(f" ✅ {created}/{count} Accounts erstellt") return created def create_contacts(session, count): print(f"\n👤 Erstelle {count} Kontakte...") created = 0 for i in range(count): first = FIRST_NAMES[i % len(FIRST_NAMES)] last = LAST_NAMES[i % len(LAST_NAMES)] result = call_api("set_entry", { "session": session, "module_name": "Contacts", "name_value_list": { "first_name": {"name": "first_name", "value": first}, "last_name": {"name": "last_name", "value": f"{last} (Seed {i+1})"}, "email1": {"name": "email1", "value": f"{first.lower()}.{last.lower()}{i}@example.com"}, "phone_work": {"name": "phone_work", "value": f"+49 170 {1000000+i}"}, } }) if result.get("id"): created += 1 if (i+1) % 20 == 0: print(f" ... {i+1}/{count}") time.sleep(0.1) print(f" ✅ {created}/{count} Kontakte erstellt") return created def create_leads(session, count): print(f"\n🎯 Erstelle {count} Leads...") created = 0 for i in range(count): first = FIRST_NAMES[(i+5) % len(FIRST_NAMES)] last = LAST_NAMES[(i+3) % len(LAST_NAMES)] result = call_api("set_entry", { "session": session, "module_name": "Leads", "name_value_list": { "first_name": {"name": "first_name", "value": first}, "last_name": {"name": "last_name", "value": f"{last} (Lead {i+1})"}, "lead_source": {"name": "lead_source", "value": "API Import"}, "status": {"name": "status", "value": "New"}, } }) if result.get("id"): created += 1 if (i+1) % 20 == 0: print(f" ... {i+1}/{count}") time.sleep(0.1) print(f" ✅ {created}/{count} Leads erstellt") return created def get_counts(session): """Count records in key modules.""" modules = ["Accounts", "Contacts", "Leads", "Opportunities", "Cases"] print(f"\n📊 Datenbank-Inhalt:") for mod in modules: result = call_api("get_entries_count", { "session": session, "module_name": mod, "query": "", "deleted": 0 }) count = result.get("result_count", "?") print(f" {mod:15s}: {count}") def main(): parser = argparse.ArgumentParser(description="SugarCRM 6.5 CE - Massendaten-Generator") parser.add_argument("--count", type=int, default=10, help="Anzahl Datensätze pro Typ") parser.add_argument("--clean", action="store_true", help="Nur Zählen, keine Daten") args = parser.parse_args() print("=" * 60) print("🍬 SugarCRM 6.5.26 CE — Massendaten-Generator") print(f" URL: http://{BASE_URL}") print("=" * 60) session = login() if args.clean: get_counts(session) print("\n✅ Fertig (nur Zählung).") return count = args.count total = 0 total += create_accounts(session, count) total += create_contacts(session, count) total += create_leads(session, count) get_counts(session) print(f"\n{'=' * 60}") print(f"✅ {total} Datensätze erstellt!") print(f"{'=' * 60}") if __name__ == "__main__": main()