Commit graph

108 commits

Author SHA1 Message Date
nickviljoen
b7e0430636 Fix: Prevent DAM folder creation attempts causing timeouts
Remove folder creation logic in get_or_create_subfolder_path() since DAM does not allow folder creation via API. When a subfolder doesn't exist, upload to the parent folder instead of attempting to create it (which was causing 120 second timeouts).

This resolves upload failures in PROD environment during A2→A3 workflow.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-30 10:34:53 +02:00
nickviljoen
04eccab9e7 Enhancement: Add environment-specific configurations and metadata improvements
This commit includes critical updates for PPR deployment:

1. Environment-Specific Field Mappings:
   - Created field_mappings_ppr.yaml with agency code "Oliver"
   - Created field_mappings_prod.yaml with agency code "0000221659"
   - Updated config_loader.py to auto-detect environment based on DAM URL
   - Enables seamless deployment between PPR and PROD environments

2. Metadata Extractor Enhancements:
   - Added MetadataTable extraction support for nested fields
   - Enables extraction of "Type of Video & Static Right" multi-value field
   - Added logic to apply defaults to existing but empty fields
   - Fixed agency name display_value handling for domain fields

3. Default Values Added:
   - VIDEO_POST_PROD_COMPANY: "Oliver Marketing Ltd"
   - AUDIO_POST_PROD_COMPANY: "Oliver Marketing Ltd"
   - PROD_COMPANY (Production House): "-"

These changes ensure:
- Correct agency codes per environment (PPR/PROD)
- Proper extraction of nested tabular fields
- Default values for empty production company fields
- Seamless deployment workflow

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-28 20:41:21 +02:00
nickviljoen
f83b4fae3e PPR Environment: Use SIMPLE metadata structure for tabular fields
Key Changes:
- Updated metadata_extractor_mvp.py to use SIMPLE structure for all tabular fields
- All tabular fields now use direct value objects (no MetadataTableFieldRow wrapper)
- MAIN_LANGUAGES, ASSETCOMPLIANCE, MARKETING_TAG, CREATIVEX all use SIMPLE structure
- Master Asset ID field updated to SIMPLE structure
- Date fields now use type 'string' instead of 'long'
- Matches DAM reference structure from asset_representation.json

Added Files:
- metadata_extractor_mvp_PROD.py: PROD-specific version with same SIMPLE structure
- Backup files for safety
- Analysis and comparison documentation

Environment:
- Tested and working in PPR environment (ppr.dam.ferrero.com)
- All tabular fields match DAM-supplied reference structure
- Successful uploads confirmed

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-23 16:52:50 +02:00
DJP
5a2273459c Fix: Restore MAIN_LANGUAGES and defaults to exact working structure from before Jan 19 changes 2026-01-20 08:37:41 -05:00
DJP
827a90ae71 Fix: Restore field_value wrapper to MAIN_LANGUAGES and defaults - revert to working structure 2026-01-20 08:06:52 -05:00
DJP
e77a385cce Fix: Remove field_value wrapper from MAIN_LANGUAGES to resolve null value error 2026-01-19 12:07:43 -05:00
DJP
a74d0914f9 Fix: Change date field type from 'date' to 'string' for MM/DD/YYYY format 2026-01-19 11:59:13 -05:00
DJP
4279bbc229 Fix: Correct JSON nesting for MAIN_LANGUAGES and Default Tabular Fields 2026-01-19 11:55:58 -05:00
DJP
c01b69e2fb Fix: Add MetadataTableFieldRow wrapper to all Tabular Fields (MAIN_LANGUAGES, CreativeX, Defaults) 2026-01-19 11:50:33 -05:00
DJP
4a1a4fffa0 Fix: Update Asset Validity date format to MM/DD/YYYY 2026-01-19 11:38:23 -05:00
DJP
fae3111467 Fix: Update Asset Validity date format to YYYY-MM-DD 2026-01-19 11:23:33 -05:00
DJP
e2c2719055 Fix: Add MetadataTableFieldRow wrapper to Tabular Master Asset ID field 2026-01-19 10:51:20 -05:00
DJP
4b5cb0a98a Fix: Correct inner column ID for Tabular Master Asset ID field 2026-01-19 10:45:47 -05:00
DJP
2ef92674d3 Feat: Add subfolder path to A2->A3 email notifications 2026-01-19 10:20:51 -05:00
DJP
ee6afe0888 Feat: Configurable Master Asset ID & Fix Date Type 2026-01-19 09:40:55 -05:00
DJP
0f984f3d7b Fix: Update asset validity date format to ISO-8601 string 2026-01-16 13:53:41 -05:00
DJP
631dba4390 Fix campaign ID storage - always set local_campaign_id
Critical Fix:
- extract_global_campaign_reference() now accepts campaign_id parameter
- Always sets local_campaign_id to current campaign as fallback
- Prevents NULL local_campaign_id when no Global Campaign Reference exists

Root Cause:
- Assets without Global Campaign Reference had NULL local_campaign_id
- Caused derivatives to be linked to wrong campaigns
- Same asset in multiple campaigns would share tracking IDs incorrectly

Impact:
- Every asset now has proper local_campaign_id
- Derivatives correctly linked to their source campaign
- Fixes issue where C000001177 assets were showing as C000002098

Changes:
- database.py: Added campaign_id parameter with fallback logic
- a1_to_a2_box_uploader.py: Pass campaign_number to function
- a5_to_a6_download.py: Pass campaign_number to function
2025-12-22 11:37:58 -05:00
DJP
5586dcc5de Simplify derivative storage - only store dam_asset_id
Reverted master_asset_id changes per user feedback:
- tracking_id already links derivatives to masters
- No need for additional master_asset_id foreign key
- Only storing dam_asset_id for DAM asset tracking

Changes:
- Reverted get_master_asset() to not return database 'id'
- Updated store_derivative_asset() to only INSERT dam_asset_id
- Updated a2_to_a3_upload_polling.py to pass None for master_asset_id
- Removed master_asset_id from INSERT statement

Note: Migration script still needed for dam_asset_id column only
2025-12-22 10:16:14 -05:00
DJP
c901a79e24 Fix A2→A3 email template and database logging issues
Email Template Fix:
- Fixed subject line syntax error in a2_to_a3_batch_complete template
- Removed Jinja2 control flow ({% if %}) from subject line
- Changed to simple expression-only format
- Fixes 'Failed to send email' error

Database Logging Fix:
- Updated get_master_asset() to return database primary key 'id'
- Updated store_derivative_asset() to actually store master_asset_id and dam_asset_id
- Updated a2_to_a3_upload_polling.py to pass master_asset['id'] instead of None
- Added migration script to add dam_asset_id column to derivative_assets table
- Fixes issue where derivatives weren't being linked to masters in database
- Enables proper lookups and tracking of uploaded derivatives

Impact:
- Email notifications will now send successfully
- Derivatives will be properly logged and linked to master assets
- Other tools can now find uploaded derivatives in database
2025-12-22 10:12:36 -05:00
DJP
222a53f466 Fix date field type error for ASSET VALIDITY START/END PERIOD
- Convert dates to milliseconds since epoch (Unix timestamp × 1000)
- Change field type from 'string' to 'long' for DATE fields
- Add _set_date_field_value() helper method for proper date handling
- Fixes 'java.lang.String was specified. Expecting java.util.Date' error
- Applies to A2->A3 uploads
2025-12-19 23:02:55 -05:00
DJP
5e8745580a Fix folder detection for folders with periods (v2)
- Enhanced logic to detect false-positive extensions like '. REFERENCE FILES'
- Checks if extension starts with period + space/uppercase (indicates folder name)
- Checks if extension contains spaces (not a valid file extension)
- Properly handles edge cases: '01. REFERENCE FILES', '02. OPEN FILES'
- Tested with multiple scenarios to ensure accuracy
2025-12-17 13:14:59 -05:00
DJP
6d7aa7e95a Fix folder detection for folders with periods in names
- Enhanced _get_assets_recursive() to properly identify folders vs files
- Added resource_type field validation (more reliable than asset_type)
- Created whitelist of 40+ known file extensions for accurate detection
- Fixes HTTP 404 errors when processing folders like '01. REFERENCE FILES'
- Applies to both A1->A2 and B1->B2 workflows
2025-12-17 13:06:02 -05:00
DJP
599d468e44 Add Master Asset ID field to A2→A3 uploads
- Added ARTESIA.FIELD.ASSET_ID to MVP fields in field_mappings.yaml
- Updated metadata_extractor_mvp.py to accept master_opentext_id parameter
- Added _add_master_asset_id_field() and _get_field_id() helper methods
- Modified a2_to_a3_upload_polling.py to pass master asset's opentext_id
- Field is populated with original master asset's DAM ID for derivative tracking
- Field is omitted for new assets (tracking ID with -N suffix)
- Covers both A2→A3 standard derivatives and A5→A6 reworked assets
2025-12-15 17:28:30 -05:00
DJP
a7d17dd00d Add CSV attachment with campaign details to A1 and B1 success emails 2025-12-07 19:27:36 -05:00
DJP
9a3bf5d9cd Implement Master Tracking ID validation for A2-A3 uploads 2025-12-06 17:21:38 -05:00
DJP
160ef8ad43 Implement prefix-based tracking ID system for master files
- Master files (B1→B2) now always start with 'M' prefix
- Regular files (A1→A2, A5→A6) never start with 'M'
- Updated generate_unique_tracking_id() to accept is_master parameter
- All tracking IDs remain 6 characters in length
- No database schema changes required
2025-12-06 10:01:05 -05:00
DJP
4724fa3333 feat: Add A2-A3 batch upload completion notification template. 2025-12-03 17:05:39 -05:00
DJP
bce739d116 feat: Automatically set asset validity dates in the metadata extractor and update the agency name in field mappings. 2025-12-03 14:28:59 -05:00
DJP
ea2e313185 feat: Add systemd services and timers for daily and weekly database backups, introduce a token retrieval script, and update the backup guide documentation. 2025-12-01 22:19:24 -05:00
DJP
ca11c0dbb4 Fix NameError: Restore missing import in dam_client.py 2025-12-01 15:31:30 -05:00
DJP
69ffdeb14e Add CreativeX service runner and fix dam_client indentation 2025-12-01 15:29:27 -05:00
DJP
5f389f6490 Implement robust Box name sanitization in shared/common.py 2025-12-01 15:23:01 -05:00
DJP
499399d6c6 Sanitize subfolder names in dam_client recursive search 2025-12-01 15:16:55 -05:00
DJP
4d1e71d978 Implement true recursion in DAM client: treat items without extensions as folders 2025-12-01 14:54:21 -05:00
DJP
0f6e816255 Fix recursive download in B1->B2 script: improve folder identification and add safeguards 2025-12-01 14:17:14 -05:00
DJP
17648d9051 Fix test_connection to not use non-existent /v6 endpoint 2025-11-26 16:58:55 -05:00
DJP
532699f634 Show full OAuth tokens in logs for debugging 2025-11-26 16:44:07 -05:00
DJP
b2c8e01d4b Add token preview logging for OAuth tokens 2025-11-26 16:32:10 -05:00
DJP
c7ddf1d45f Add verbose logging for all DAM API requests 2025-11-26 16:26:15 -05:00
DJP
37cab9d902 Add support for loading environment-specific .env files (prod/dev) 2025-11-26 15:44:09 -05:00
DJP
9d207d0480 chore: Update DAM mTLS base and OAuth URLs in production environment to /token endpoint. 2025-11-26 10:18:56 -05:00
DJP
c1f338022c fix: Ensure type field is added when updating CreativeX URL
- Modified _set_field_value to include 'type': 'string' in all code paths
- Adds type field when updating existing CreativeX URL field
- Ensures consistent structure whether creating or updating field
2025-11-25 09:14:25 -05:00
DJP
80316cad32 fix: Add missing type field to CreativeX URL metadata
- Added 'type': 'string' to FERRERO.FIELD.CREATIVEX LINK value structure
- Fixes DAM validation error for CreativeX URL field
- Structure now matches DAM requirements
2025-11-25 09:11:41 -05:00
DJP
548c30344b feat: Support multiple CreativeX platforms in metadata
- Updated creativex_scoring_storing.py to map multiple placements to platforms
- Modified get_mapped_platform to get_mapped_platforms (returns list)
- Updated a2_to_a3_upload_polling.py to retrieve platforms list from DB
- Enhanced metadata_extractor_mvp.py to build multi-value CreativeX field
- Added DAM-CX mappings.csv for channel/placement to platform mapping
- Supports single channel with multiple placements generating multiple Platform^Score values
2025-11-24 14:44:11 -05:00
DJP
0af15563bc feat: Implement new Python script locking, relocate PHP workflow, and update Python scripts and documentation. 2025-11-21 17:20:34 -05:00
DJP
2cad2c2955 Fix AttributeError in DAMClient.test_connection 2025-11-21 16:57:43 -05:00
DJP
6fe2ba234b Implement Auth V2 (Hybrid mTLS/OAuth) and update field mappings 2025-11-21 16:46:37 -05:00
DJP
b906434f67 Add A1->A2 and A4 Box CSV uploader scripts 2025-11-20 22:52:26 -05:00
DJP
20a187a61d feat: Add Python project dependencies. 2025-11-20 22:45:04 -05:00
DJP
0bf3c34cd0 Add asset type mapping from 3-letter codes to DAM codes
Maps frontend naming tool 3-letter codes (EHI, IMG, TVC) to DAM's
lowercase descriptive codes (heroimage, keyvisual, tvc) for uploads.

New File: config/asset_type_mappings.yaml
- 45 asset type mappings from DAM lookup domains
- Maps 3-letter codes to DAM codes
- E-Commerce types: EHI→heroimage, EBS→beautyshot, etc.
- Standard types: IMG→keyvisual, TVC→tvc, etc.
- Expandable as new asset types added

Field Mappings Update (field_mappings.yaml):
- Added FERRERO.FIELD.MKTG.ASSET TYPE to filename_updates
- Source: asset_type (from parsed filename)
- Required: true

Metadata Extractor Updates (metadata_extractor_mvp.py):
- Added _load_asset_type_mappings() method
- Added _map_asset_type() method
- Integrated mapping into _update_fields()
- Logs mappings: "Asset type mapping: EHI -> heroimage"
- Warns if no mapping found (may fail DAM validation)

Example Flow:
1. Filename: ROC_TEST-E2E2_EHI_1x1_DE_de.png
2. Parse: asset_type = "EHI"
3. Map: EHI → "heroimage"
4. Update field: FERRERO.FIELD.MKTG.ASSET TYPE = "heroimage"
5. DAM accepts "heroimage" (valid domain value)

Without Mapping (before):
- Field value: "EHI"
- DAM validation: FAILS (EHI not in domain)

With Mapping (after):
- Field value: "heroimage"
- DAM validation: PASSES 

Complete Mapping List (45 types):
E-Commerce: ECA, ECB, EBS, EBR, EEM, EHI, EIL, EOP, EUG, EWB
Standard: 3RT, APC, BBK, BRC, BSG, CKV, CID, DAT, FLA, FNT, GDT,
         GRG, IMG, FPO, LGL, LOG, MLF, OLV, PAW, PKI, POS, PDM,
         PRI, QRC, SND, SIP, SGL, TVC, VIE

DAM Answer: Uses descriptive lowercase codes, not 3-letter codes.
Frontend uses 3-letter for brevity, backend maps to DAM format.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-14 13:08:01 -05:00