- Add wrike_monitor_lgl.py for LGL Team board
* Updated API token and space configuration
* All 11 custom fields mapped correctly
* OMG# field now stores HTML links (matching LGL Team format)
* Recursive duplicate detection across entire Business Areas folder
* Handles HTML link extraction for accurate comparison
- Add discover_board_info.py
* Automated discovery tool for board configuration
* Finds space IDs, custom field IDs, and item types
* Generates configuration snippets
- Add config_lgl_team.py
* Reference configuration for LGL Team space
* Complete field mapping documentation
- Add test_duplicate_detection.py
* Testing tool to verify duplicate detection logic
* Can search for specific OMG# values
- Update requirements.txt
- Remove wrike_import.py (moved to OLD/)
Key Features:
- NO DUPLICATES: Searches entire Business Areas folder before creating
- HTML Link Support: OMG# stored as clickable links matching existing format
- Global Search: Uses descendants=true for efficient recursive search
- Format Matching: Generates OMG# links identical to existing entries
🤖 Generated with Claude Code
139 lines
6.1 KiB
Python
139 lines
6.1 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test script to verify duplicate detection works correctly
|
|
This will check if a deliverable with a specific OMG# exists in the LGL Team board
|
|
"""
|
|
|
|
import requests
|
|
|
|
# Configuration
|
|
API_TOKEN = "eyJ0dCI6InAiLCJhbGciOiJIUzI1NiIsInR2IjoiMiJ9.eyJkIjoie1wiYVwiOjY5NjM3MzksXCJpXCI6OTU5MTM2MSxcImNcIjo0NzAyNjA1LFwidVwiOjIzMjcyNDA0LFwiclwiOlwiVVNcIixcInNcIjpbXCJXXCIsXCJGXCIsXCJJXCIsXCJVXCIsXCJLXCIsXCJDXCIsXCJEXCIsXCJNXCIsXCJBXCIsXCJMXCIsXCJQXCJdLFwielwiOltdLFwidFwiOjB9IiwiaWF0IjoxNzY2MDAwNjMyfQ.FwtNCIiBUbb82MlEnI_Z3vKt-W8IgKRwLwZY6IY6fEI"
|
|
API_BASE = "https://www.wrike.com/api/v4"
|
|
SPACE_ID = "MQAAAABoHcTY" # LGL Team
|
|
OMG_NUMBER_FIELD_ID = "IEAGUQQ3JUAJL7YF"
|
|
|
|
def make_request(endpoint):
|
|
"""Make a GET request to Wrike API"""
|
|
url = f"{API_BASE}{endpoint}"
|
|
headers = {
|
|
"Authorization": f"Bearer {API_TOKEN}",
|
|
"Content-Type": "application/json"
|
|
}
|
|
try:
|
|
response = requests.get(url, headers=headers, timeout=30)
|
|
response.raise_for_status()
|
|
return response.json()
|
|
except requests.exceptions.RequestException as e:
|
|
print(f"❌ API Error: {e}")
|
|
return None
|
|
|
|
def find_deliverable_by_omg(folder_id, omg_number):
|
|
"""Find deliverable with matching OMG number"""
|
|
print(f"\n🔍 Searching for deliverable with OMG# {omg_number} in folder {folder_id}...")
|
|
|
|
# Get all subfolders/projects
|
|
result = make_request(f"/folders/{folder_id}/folders")
|
|
|
|
if result and "data" in result:
|
|
# Find parent folder with childIds
|
|
parent_folder = None
|
|
for item in result["data"]:
|
|
if item["id"] == folder_id:
|
|
parent_folder = item
|
|
break
|
|
|
|
if parent_folder:
|
|
child_ids = parent_folder.get("childIds", [])
|
|
print(f" Found {len(child_ids)} child items to check")
|
|
|
|
# For each child, get its details with custom fields
|
|
for child_id in child_ids:
|
|
child_result = make_request(f"/folders/{child_id}")
|
|
if child_result and "data" in child_result and len(child_result["data"]) > 0:
|
|
child = child_result["data"][0]
|
|
|
|
# Check if it's a project (deliverable)
|
|
if "project" in child:
|
|
custom_fields = child.get("customFields", [])
|
|
for field in custom_fields:
|
|
if field.get("id") == OMG_NUMBER_FIELD_ID:
|
|
field_value = field.get("value")
|
|
if field_value == omg_number:
|
|
print(f" ✅ FOUND: '{child['title']}' (ID: {child_id}) has OMG# {field_value}")
|
|
return child_id
|
|
else:
|
|
print(f" - '{child['title']}' has OMG# {field_value} (doesn't match)")
|
|
|
|
print(f" ❌ NOT FOUND: No deliverable with OMG# {omg_number}")
|
|
return None
|
|
|
|
def list_recent_deliverables_with_omg(space_id):
|
|
"""List some existing deliverables with their OMG numbers"""
|
|
print(f"\n📋 Listing existing deliverables with OMG# in space {space_id}...")
|
|
print("="*80)
|
|
|
|
# Get top-level folders in space
|
|
result = make_request(f"/folders/{space_id}/folders")
|
|
|
|
if result and "data" in result:
|
|
# Find space folder with childIds
|
|
space_folder = None
|
|
for item in result["data"]:
|
|
if item["id"] == space_id:
|
|
space_folder = item
|
|
break
|
|
|
|
if space_folder:
|
|
child_ids = space_folder.get("childIds", [])[:5] # Limit to first 5 folders
|
|
|
|
for folder_id in child_ids:
|
|
folder_result = make_request(f"/folders/{folder_id}/folders")
|
|
|
|
if folder_result and "data" in folder_result:
|
|
for item in folder_result["data"]:
|
|
if "project" in item:
|
|
custom_fields = item.get("customFields", [])
|
|
for field in custom_fields:
|
|
if field.get("id") == OMG_NUMBER_FIELD_ID:
|
|
omg_value = field.get("value", "N/A")
|
|
print(f" • {item['title']}")
|
|
print(f" OMG#: {omg_value}")
|
|
print(f" ID: {item['id']}")
|
|
print()
|
|
|
|
def main():
|
|
print("""
|
|
╔════════════════════════════════════════════════════════════════╗
|
|
║ DUPLICATE DETECTION TEST ║
|
|
║ Verifies that the script can find existing deliverables ║
|
|
╚════════════════════════════════════════════════════════════════╝
|
|
""")
|
|
|
|
# List some existing deliverables
|
|
list_recent_deliverables_with_omg(SPACE_ID)
|
|
|
|
# Test duplicate detection
|
|
print("\n" + "="*80)
|
|
print("TESTING DUPLICATE DETECTION")
|
|
print("="*80)
|
|
|
|
# You can test with a known OMG# from the list above
|
|
test_omg = input("\nEnter an OMG# to test (or press Enter to skip): ").strip()
|
|
|
|
if test_omg:
|
|
# You'll need to provide a folder ID to search in
|
|
test_folder = input("Enter the folder/project ID to search in: ").strip()
|
|
|
|
if test_folder:
|
|
result = find_deliverable_by_omg(test_folder, test_omg)
|
|
|
|
if result:
|
|
print(f"\n✅ SUCCESS: Duplicate detection would catch this!")
|
|
print(f" The script would SKIP creating a new deliverable")
|
|
print(f" and use existing ID: {result}")
|
|
else:
|
|
print(f"\n✅ SUCCESS: OMG# {test_omg} not found")
|
|
print(f" The script would CREATE a new deliverable")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|