#!/usr/bin/env bash # Rename to better reflect purpose - only applied to weight measures (г, г., грамм, etc) WEIGHT_PRICE_MULTIPLIER=${WEIGHT_PRICE_MULTIPLIER:-10} SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) source $SCRIPT_DIR/constants.sh source $ROOT_DIR/run/evo/constants.sh source $SCRIPT_DIR/functions.sh # Setup logging setup_logging # Trap signals to ensure proper cleanup trap 'cleanup 1' HUP INT QUIT TERM # Function to check if a measure is a weight measure is_weight_measure() { local measure="$1" # Convert to lowercase for case-insensitive comparison local measure_lower=$(echo "$measure" | tr '[:upper:]' '[:lower:]') # Check for various weight measure formats if [[ "$measure_lower" == "г" || "$measure_lower" == "г." || "$measure_lower" == "грамм" || "$measure_lower" == "граммов" || "$measure_lower" == "гр" || "$measure_lower" == "гр." ]]; then return 0 # True - it is a weight measure else return 1 # False - it is not a weight measure fi } function uploadPhoto() { getUploadPhotoResp=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $VK_API_USER_TOKEN" \ "$VK_API_GET_PHOTO_UPLOAD_URL&group_id=$VK_API_GROUP_ID") http_code=${getUploadPhotoResp: -3} response_body=${getUploadPhotoResp:0:-3} echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE" # Check if the first request was successful if [[ "$http_code" != "200" ]]; then echo "$(timestamp) [ERROR] Failed to get photo upload URL" >> "$LOG_FILE" return 1 fi uploadPhotoUrl=`echo $response_body | yq -pj '.response.upload_url'` uploadPhotoObj=`curl -s -X POST --header "Content-Type: $VK_API_CONTENT_TYPE_MULTIPART" $uploadPhotoUrl -F "file=@$VK_API_PHOTO_PATH"` uploadPhotoResp=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $VK_API_USER_TOKEN" \ -F upload_response=$uploadPhotoObj \ -F v=$VK_API_VERSION \ $VK_API_UPLOAD_PHOTO_URL) http_code=${uploadPhotoResp: -3} response_body=${uploadPhotoResp:0:-3} echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE" # Check if the second request was successful if [[ "$http_code" != "200" ]]; then echo "$(timestamp) [ERROR] Failed to upload photo" >> "$LOG_FILE" return 1 fi # Extract and return the photo ID - update to use the correct JSON path local photoId=$(echo "$response_body" | yq -pj '.response.photo_id') echo "$(timestamp) [INFO] Uploaded photo with ID: $photoId" >> "$LOG_FILE" echo $photoId } evoPath=$EVO_PRODUCTS_PATH/$EVO_API_STORE_ID evoFileName=`ls $evoPath -Art | tail -1` evoFilePath=$evoPath/$evoFileName evoGroupsPath=$EVO_GROUPS_PATH/$EVO_API_STORE_ID evoGroupsFileName=`ls $evoGroupsPath -Art | tail -1` evoGroupsFilePath=$evoGroupsPath/$evoGroupsFileName vkPath=$VK_PRODUCTS_PATH/$VK_API_GROUP_ID vkFileName=`ls $vkPath -Art | tail -1` vkFilePath=$vkPath/$vkFileName vkAlbumPath=$VK_ALBUMS_PATH/$VK_API_GROUP_ID vkAlbumFileName=`ls $vkAlbumPath -Art | tail -1` vkAlbumFilePath=$vkAlbumPath/$vkAlbumFileName # Load whitelist readarray -t whitelist < "$ROOT_DIR/vk/whitelist" readarray items < <(yq -o=j -I=0 '.items[]' $evoFilePath ) for item in "${items[@]}"; do evoTitle=`echo $item | yq .name` evoGroupId=`echo $item | yq .parent_id` evoGroupName=`evoGroupId="$evoGroupId" yq -r '.items[] | select(.id==strenv(evoGroupId)) | .name' $evoGroupsFilePath` # Check if group is whitelisted if [[ ! " ${whitelist[@]} " =~ " ${evoGroupName} " ]]; then continue fi vkAlbumId=`albumName="$evoGroupName" yq '.response.items[] | select(.title==strenv(albumName)) | .id' $vkAlbumFilePath` name=`echo $item | yq .name | xargs` # Replace semicolons with commas for VK API compatibility name_for_vk="${name//;/,}" measure=`echo $item | yq .measure_name` # Calculate price based on measure type base_price=$(echo $item | yq .price) if is_weight_measure "$measure"; then # Apply multiplier for weight measures price=$((base_price * WEIGHT_PRICE_MULTIPLIER)) price_info="${WEIGHT_PRICE_MULTIPLIER}$measure" else # No multiplier for non-weight measures price=$base_price price_info="$measure" fi quantity=`echo $item | yq .quantity` allow_to_sell=`echo $item | yq .allow_to_sell` # Set stock amount based on allow_to_sell flag if [[ "$allow_to_sell" = "true" ]]; then stock_amount=$VK_STOCK_AMOUNT else stock_amount=0 fi desc="$name (цена за ${price_info}.) " description=$(echo $item | yq '.description // ""') if [[ -n "$description" ]]; then desc+="$description" fi article=`echo $item | yq .article_number` found=0 readarray vkItems < <(yq -o=j -I=0 '.response.items[]' $vkFilePath ) for vkItem in "${vkItems[@]}"; do vkTitle=`echo $vkItem | yq .title` vkTitleTrimmed="$(echo "$vkTitle" | xargs)" evoTitleTrimmed="$(echo "$evoTitle" | xargs)" # For comparison, transform EVO title the same way (replace ; with ,) evoTitleForVk="${evoTitleTrimmed//;/,}" if [[ "$vkTitleTrimmed" = "$evoTitleForVk" ]]; then found=1 originalName=$(echo "$vkItem" | yq .title | xargs) originalDesc=$(echo "$vkItem" | yq .description | xargs) originalPrice=$(echo "$vkItem" | yq .price.amount) originalPrice=$((originalPrice / 100)) originalArticle=$(echo "$vkItem" | yq .sku | xargs) originalStockAmount=$(echo "$vkItem" | yq .stock_amount) # Debug output to log file echo "$(timestamp) [DEBUG] name='$name' originalName='$originalName'" >> "$LOG_FILE" echo "$(timestamp) [DEBUG] desc='$desc' originalDesc='$originalDesc'" >> "$LOG_FILE" echo "$(timestamp) [DEBUG] price='$price' originalPrice='$originalPrice'" >> "$LOG_FILE" echo "$(timestamp) [DEBUG] stock_amount='$stock_amount' allow_to_sell='$allow_to_sell'" >> "$LOG_FILE" # Normalize descriptions more carefully to maintain proper spacing # Replace newlines with spaces first, then normalize spaces and trim normalized_desc=$(echo "$desc" | sed 's/\n/ /g' | tr -s ' ' | xargs) normalized_orig_desc=$(echo "$originalDesc" | sed 's/\n/ /g' | tr -s ' ' | xargs) # Apply semicolon-to-comma transformation for consistent comparison normalized_desc="${normalized_desc//;/,}" normalized_orig_desc="${normalized_orig_desc//;/,}" # Check for changes if [[ "$(echo "$name_for_vk" | xargs)" != "$originalName" ]]; then name_changed="true" else name_changed="false" fi if [[ "$price" != "$originalPrice" ]]; then price_changed="true" else price_changed="false" fi if [[ "$normalized_desc" != "$normalized_orig_desc" ]]; then desc_changed="true" else desc_changed="false" fi if [[ "$stock_amount" != "$originalStockAmount" ]]; then stock_changed="true" else stock_changed="false" fi # Check if update is needed if [[ "$name_changed" == "true" || "$price_changed" == "true" || "$desc_changed" == "true" || "$stock_changed" == "true" ]]; then productId=$(echo "$vkItem" | yq .id) echo "$(timestamp) [REQUEST] Updating product: $name_for_vk (name_changed=$name_changed, price_changed=$price_changed, desc_changed=$desc_changed, stock_changed=$stock_changed)" >> "$LOG_FILE" response=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $VK_API_USER_TOKEN" \ -F owner_id="$VK_API_PARAM_OWNER_ID" \ -F item_id=$productId \ -F name="$name_for_vk" \ -F description="$normalized_desc" \ -F category_id=$VK_API_CATEGORY_ID \ -F price="$price" \ -F stock_amount="$stock_amount" \ $VK_API_EDIT_PRODUCT) http_code=${response: -3} response_body=${response:0:-3} echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE" fi fi done if [[ "$found" = 0 ]] && [[ "$allow_to_sell" = "true" ]] ; then photoId=$(uploadPhoto) # Check if photo upload was successful if [[ -z "$photoId" || "$photoId" == "null" ]]; then echo "$(timestamp) [ERROR] Failed to get valid photo ID, skipping product: $name" >> "$LOG_FILE" continue fi echo "$(timestamp) [REQUEST] Creating product: $name_for_vk" >> "$LOG_FILE" response=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $VK_API_USER_TOKEN" \ -F owner_id=$VK_API_PARAM_OWNER_ID \ -F name="$name_for_vk" \ -F description="$desc" \ -F category_id=$VK_API_CATEGORY_ID \ -F price=$price \ -F main_photo_id=$photoId \ -F stock_amount="$stock_amount" \ $VK_API_ADD_PRODUCT) http_code=${response: -3} response_body=${response:0:-3} echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE" # Check if product creation was successful if [[ "$http_code" != "200" ]] || [[ $(echo $response_body | grep -c "error") -gt 0 ]]; then echo "$(timestamp) [ERROR] Failed to create product: $name" >> "$LOG_FILE" continue fi productId=$(echo $response_body | yq .response.market_item_id) # Only proceed if we got a valid product ID if [[ -n "$productId" && "$productId" != "null" ]]; then resp=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $VK_API_USER_TOKEN" \ "$VK_API_ADD_PRODUCT_TO_ALBUM&owner_id=$VK_API_PARAM_OWNER_ID&item_ids=$productId&album_ids=$vkAlbumId") http_code=${resp: -3} response_body=${resp:0:-3} echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE" else echo "$(timestamp) [ERROR] Invalid product ID, skipping album addition for: $name" >> "$LOG_FILE" fi fi done # Use the cleanup function instead of directly exiting cleanup 0