4.2 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Project Overview
SAP C4C (Cloud for Customer) attachment downloader toolkit that retrieves attachments from ServiceRequest tickets and optionally uploads them to Synology DSM NAS.
sap-c4c-AttachmentFolder.py: Core downloader (Python >= 3.8) using OData APIs and web scrapingC4CAttachmentDownloader.java: Java wrapper that calls the Python script via ProcessBuilderdsm-upload.py: Standalone Synology NAS upload example
Common Commands
# Install dependencies
pip install requests scrapling[all] playwright
python -m playwright install chromium
# Download attachments
python sap-c4c-AttachmentFolder.py \
--tenant https://xxx.c4c.saphybriscloud.cn \
--user admin --password xxx --ticket 24588
# Download with custom concurrency (default: 5 threads)
python sap-c4c-AttachmentFolder.py --ticket 24588 --max-workers 10
# List attachments only (no download)
python sap-c4c-AttachmentFolder.py --ticket 24588 --list-only
# JSON mode (for Java/programmatic use)
python sap-c4c-AttachmentFolder.py --ticket 24588 --json
# Download + upload to Synology DSM
python sap-c4c-AttachmentFolder.py --ticket 24588 \
--dsm-url http://10.0.10.235:5000 --dsm-user PLM \
--dsm-password 123456 --dsm-path /Newgonow/AU-SPFJ
# All credentials also accept environment variables:
# C4C_TENANT, C4C_USERNAME, C4C_PASSWORD, DSM_URL, DSM_USERNAME, DSM_PASSWORD, DSM_PATH
// Java: compile requires Jackson (jackson-databind, jackson-core, jackson-annotations)
javac -cp jackson-databind.jar:jackson-core.jar:jackson-annotations.jar C4CAttachmentDownloader.java
Architecture
Data Flow
- Authenticate to SAP C4C via Basic Auth
- Look up ServiceRequest by ticket ID -> get ObjectID and SerialID
- Fetch SR-level attachments via
/sap/c4c/odata/v1/c4codata/ServiceRequestCollection('{OID}')/ServiceRequestAttachmentFolder - Fetch XIssueItem-level attachments via
/sap/c4c/odata/cust/v1/custticketapi/BO_XSRIssueItemAttachmentCollection(two-step: filter by UUID, then navigate to AttachmentFolder) - Download concurrently using ThreadPoolExecutor:
- CategoryCode "2" (file): OData
$valueendpoint orDocumentLinkURL - CategoryCode "3" (link): Scrapling + Playwright opens Salesforce URL, clicks
button.downloadbutton[title='Download'], captures download
- CategoryCode "2" (file): OData
- Optionally upload to Synology DSM via FileStation API, then auto-delete local files
Two OData Endpoints
/sap/c4c/odata/v1/c4codata(ODATA_C4C) - Standard C4C OData for ServiceRequest and SR-level attachments/sap/c4c/odata/cust/v1/custticketapi(ODATA_CUST) - Custom ticket API for XIssueItem and its attachments
Java Wrapper
Invokes Python script with --json flag, passes credentials via environment variables (not CLI args for security). Parses JSON into typed classes: Result, Attachment, IssueItem, DownloadedFile, DsmUploadEntry. Default timeout: 30 minutes.
DSM Upload Directory Structure
- SR attachments:
{DSM_PATH}/{ticketID}_{serialID}/{filename} - IssueItem attachments:
{DSM_PATH}/{ticketID}_{serialID}/{issueID}/{filename}
Concurrency Model
Multi-threaded via ThreadPoolExecutor (default 5, --max-workers). Both file and link downloads are submitted as futures. Thread-safe console output uses a print_lock. The requests.Session is shared across file-download threads (thread-safe). Scrapling/Playwright link downloads each launch their own browser.
Global State
The Python script uses module-level globals (TENANT, USERNAME, PASSWORD, ODATA_C4C, ODATA_CUST, OUTPUT_DIR, DSM_*, MAX_WORKERS) initialized in main(). The run() function is the core entry point returning a structured dict.
Troubleshooting
- Playwright not installed:
python -m playwright install chromium - Link download fails: Salesforce page selector
button.downloadbutton[title='Download']may have changed; updatedownload_link_via_scrapling() - Timeout: Increase Java wrapper timeout or Scrapling's
timeoutparam (currently 60s page load, 120s download wait) - SSL warnings:
verify=Falseis used throughout;urllib3warnings are suppressed