File size: 3,453 Bytes
5c8f5bf
8986db1
 
 
 
 
5c8f5bf
 
8986db1
5c8f5bf
8986db1
5c8f5bf
 
 
 
8986db1
5c8f5bf
 
 
 
8986db1
5c8f5bf
 
8986db1
 
 
 
 
 
 
 
 
 
5c8f5bf
 
f746ed1
8986db1
5c8f5bf
 
8986db1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5c8f5bf
8986db1
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import json
import hmac
import hashlib
import base64
import time
from datetime import datetime
from logger_manager import log_info, log_error
import os
import aiohttp

from env import VUFORIA_SERVER_ACCESS_KEY, VUFORIA_SERVER_SECRET_KEY,UPLOADED_IMAGES_DIR

async def add_target_to_vuforia(image_name: str, image_path: str) -> str:
    """
    Adds a target to the Vuforia database and returns the Vuforia target ID.
    Implements proper Vuforia authentication and request format.
    """
    log_info(f"Adding target {image_name} to Vuforia")

    try:
        # Read image data
        with open(image_path, "rb") as image_file:
            image_data = image_file.read()
        
        # Base64 encode the image
        image_base64 = base64.b64encode(image_data).decode('utf-8')
        
        # Create request data
        request_path = '/targets'
        host = 'vws.vuforia.com'
        url = f"https://{host}{request_path}"
        
        # Create payload
        payload = {
            "name": image_name,
            "width": 150.0,  # Default width in scene units
            "image": image_base64,
            "active_flag": True,
        }
        
        # Convert payload to JSON
        body = json.dumps(payload)
        
        # Get current date in proper format for Vuforia
        date = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
        
        # Set content type
        content_type = 'application/json'
        
        # Calculate MD5 of request body
        content_md5 = hashlib.md5(body.encode('utf-8')).hexdigest()
        
        # Create string to sign according to Vuforia docs
        string_to_sign = f"POST\n{content_md5}\n{content_type}\n{date}\n{request_path}"
        
        # Generate signature
        signature = hmac.new(
            VUFORIA_SERVER_SECRET_KEY.encode('utf-8'),
            string_to_sign.encode('utf-8'),
            hashlib.sha1
        ).digest()
        signature_hex = base64.b64encode(signature).decode('utf-8')
        
        # Create headers
        headers = {
            'Authorization': f'VWS {VUFORIA_SERVER_ACCESS_KEY}:{signature_hex}',
            'Content-Type': content_type,
            'Date': date,
            'Content-MD5': content_md5
        }
        
        # Make the API request
        async with aiohttp.ClientSession() as session:
            async with session.post(url, headers=headers, data=body) as response:
                # Get response text and try to parse as JSON
                response_text = await response.text()
                try:
                    response_json = json.loads(response_text)
                except:
                    response_json = {"error": "Failed to parse response"}
                
                log_info(f"Vuforia response status: {response.status}")
                
                if response.status == 201:  # Created
                    log_info(f"Target added successfully: {response_json}")
                    return response_json.get("target_id", "unknown_target_id")
                else:
                    log_error(f"Failed to add target: Status {response.status}, Response: {response_text}")
                    raise Exception(f"Failed to add target {image_name}: Status {response.status}, Error: {response_json.get('result_code', 'Unknown')}")
                    
    except Exception as e:
        log_error(f"Error adding target {image_name}: {e}", e)
        raise