v1.
This commit is contained in:
15
.gitignore
vendored
Normal file
15
.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
*.*~$
|
||||||
|
^#*
|
||||||
|
^.#*
|
||||||
|
*~$
|
||||||
|
api.credentials*
|
||||||
|
evo/products/*
|
||||||
|
evo/groups/*
|
||||||
|
evo/stores/*
|
||||||
|
vk/categories/*
|
||||||
|
vk/albums/*
|
||||||
|
vk/products/*
|
||||||
|
run/test.log
|
||||||
|
vk/whitelist
|
||||||
|
logs/
|
||||||
|
passwords.txt
|
||||||
BIN
5393364294319597854.png
Normal file
BIN
5393364294319597854.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 151 KiB |
20
CHANGELOG.md
Normal file
20
CHANGELOG.md
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to this project will be documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [1.6.0] - 2025-06-15
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Initial changelog implementation
|
||||||
|
- Version tracking system
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
- Minor version bump from 1.5.2 to 1.6.0
|
||||||
|
|
||||||
|
## [1.5.2] - Previous Release
|
||||||
|
|
||||||
|
### Notes
|
||||||
|
- Historical version before changelog implementation
|
||||||
23
Dockerfile
Normal file
23
Dockerfile
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
FROM alpine:latest
|
||||||
|
|
||||||
|
RUN apk add --update \
|
||||||
|
curl \
|
||||||
|
git \
|
||||||
|
openrc \
|
||||||
|
bash \
|
||||||
|
jq \
|
||||||
|
yq
|
||||||
|
|
||||||
|
RUN mkdir -p /var/www/
|
||||||
|
RUN git config --system --add safe.directory '*'
|
||||||
|
|
||||||
|
COPY ./cronjobs /etc/cron.d/cronjobs
|
||||||
|
RUN chmod 0644 /etc/cron.d/cronjobs
|
||||||
|
RUN /usr/bin/crontab /etc/cron.d/cronjobs
|
||||||
|
|
||||||
|
WORKDIR /var/www/
|
||||||
|
COPY ./ /var/www/
|
||||||
|
|
||||||
|
EXPOSE 80
|
||||||
|
|
||||||
|
CMD ["/usr/sbin/crond", "-f", "-l", "8"]
|
||||||
@@ -1,2 +1,3 @@
|
|||||||
# evo-sync
|
# evo-sync
|
||||||
|
|
||||||
|
evo-sync is a command-line synchronization tool that fetches product, group, and store data from the Evo platform and syncs it with VK (VKontakte).
|
||||||
|
|||||||
27
evo/examples/products.json
Normal file
27
evo/examples/products.json
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"uuid": "0291602f-8de3-4df6-90d3-78917b51b6b5",
|
||||||
|
"group": true,
|
||||||
|
"hasVariants": null,
|
||||||
|
"type": null,
|
||||||
|
"name": "Чай с добавками",
|
||||||
|
"code": null,
|
||||||
|
"barCodes": null,
|
||||||
|
"price": null,
|
||||||
|
"costPrice": null,
|
||||||
|
"quantity": null,
|
||||||
|
"measureName": null,
|
||||||
|
"tax": null,
|
||||||
|
"allowToSell": null,
|
||||||
|
"description": null,
|
||||||
|
"articleNumber": null,
|
||||||
|
"parentUuid": null,
|
||||||
|
"alcoCodes": null,
|
||||||
|
"alcoholByVolume": null,
|
||||||
|
"alcoholProductKindCode": null,
|
||||||
|
"tareVolume": null,
|
||||||
|
"classificationCode": null,
|
||||||
|
"allowPartialSell": null,
|
||||||
|
"quantityInPackage": null,
|
||||||
|
"isExcisable": null,
|
||||||
|
"isAgeLimited": null
|
||||||
|
}
|
||||||
34
run/evo/clear.sh
Executable file
34
run/evo/clear.sh
Executable file
@@ -0,0 +1,34 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# This script cleans all EVO-related directories
|
||||||
|
# It removes all files from products, groups and stores directories
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
# Load constants and functions
|
||||||
|
source $SCRIPT_DIR/constants.sh
|
||||||
|
source $SCRIPT_DIR/functions.sh
|
||||||
|
|
||||||
|
# Initialize logging system
|
||||||
|
setup_logging
|
||||||
|
|
||||||
|
# Ensure we clean up properly even if script is interrupted
|
||||||
|
trap 'cleanup 1' HUP INT QUIT TERM
|
||||||
|
|
||||||
|
# Begin cleanup process
|
||||||
|
echo "$(timestamp) [INFO] Starting EVO cleanup process" >> "$LOG_FILE"
|
||||||
|
|
||||||
|
# Clean EVO content directories
|
||||||
|
echo "$(timestamp) [INFO] Cleaning EVO directories" >> "$LOG_FILE"
|
||||||
|
# Remove product files
|
||||||
|
echo "$(timestamp) [INFO] Removing product files" >> "$LOG_FILE"
|
||||||
|
echo "rm -f $EVO_PRODUCTS_PATH/*" && rm -rf $EVO_PRODUCTS_PATH/*
|
||||||
|
# Remove group files
|
||||||
|
echo "$(timestamp) [INFO] Removing group files" >> "$LOG_FILE"
|
||||||
|
echo "rm -f $EVO_GROUPS_PATH/*" && rm -rf $EVO_GROUPS_PATH/*
|
||||||
|
# Remove store files
|
||||||
|
echo "$(timestamp) [INFO] Removing store files" >> "$LOG_FILE"
|
||||||
|
echo "rm -rf $EVO_STORES_PATH/*" && rm -rf $EVO_STORES_PATH/*
|
||||||
|
|
||||||
|
echo "$(timestamp) [INFO] EVO cleanup completed successfully" >> "$LOG_FILE"
|
||||||
|
cleanup 0
|
||||||
21
run/evo/constants.sh
Executable file
21
run/evo/constants.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
ROOT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
ROOT_DIR+='/../..'
|
||||||
|
|
||||||
|
EVO_STORE_PERIOD_HOURS=2
|
||||||
|
EVO_STORE_PERIOD_MINUTES=$((EVO_STORE_PERIOD_HOURS * 60))
|
||||||
|
EVO_PRODUCTS_PATH="$ROOT_DIR/evo/products"
|
||||||
|
EVO_GROUPS_PATH="$ROOT_DIR/evo/groups"
|
||||||
|
EVO_STORES_PATH="$ROOT_DIR/evo/stores"
|
||||||
|
EVO_EXAMPLE_PATH="$ROOT_DIR/evo/examples"
|
||||||
|
EVO_RESPONSE_FILE_NAME_FORMAT="%(%Y-%m-%d_%H:%M:%S)T"
|
||||||
|
EVO_RESPONSE_FILE_NAME_EXT="json"
|
||||||
|
EVO_API_HOST="https://api.evotor.ru"
|
||||||
|
EVO_API_TOKEN=`cat "$ROOT_DIR/evo/api.credentials.token"`
|
||||||
|
EVO_API_STORE_ID=`cat "$ROOT_DIR/evo/api.credentials.store_id"`
|
||||||
|
EVO_API_ACCEPT=`cat "$ROOT_DIR/evo/api.credentials.accept"`
|
||||||
|
EVO_API_CONTENT_TYPE=`cat "$ROOT_DIR/evo/api.credentials.content_type"`
|
||||||
|
EVO_API_GET_PRODUCTS="$EVO_API_HOST/stores/$EVO_API_STORE_ID/products"
|
||||||
|
EVO_API_GET_GROUPS="$EVO_API_HOST/stores/$EVO_API_STORE_ID/product-groups"
|
||||||
|
EVO_API_GET_STORES="$EVO_API_HOST/stores"
|
||||||
45
run/evo/functions.sh
Executable file
45
run/evo/functions.sh
Executable file
@@ -0,0 +1,45 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Setup timestamp function
|
||||||
|
timestamp() {
|
||||||
|
date "+%Y-%m-%d %H:%M:%S"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Setup process cleanup
|
||||||
|
cleanup() {
|
||||||
|
# Kill all child processes of this script
|
||||||
|
pkill -P $$
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to handle API requests and save response
|
||||||
|
handle_request() {
|
||||||
|
local request_type=$1
|
||||||
|
local api_endpoint=$2
|
||||||
|
local path=$3
|
||||||
|
local fileName=$4
|
||||||
|
|
||||||
|
echo "$(timestamp) [REQUEST] Getting $request_type" >> "$LOG_FILE"
|
||||||
|
response=$(curl -s -w "%{http_code}" -H "Accept: $EVO_API_ACCEPT" \
|
||||||
|
-H "Content-Type: $EVO_API_CONTENT_TYPE" \
|
||||||
|
-H "Authorization: $EVO_API_TOKEN" \
|
||||||
|
-X GET \
|
||||||
|
$api_endpoint)
|
||||||
|
http_code=${response: -3}
|
||||||
|
response_body=${response:0:-3}
|
||||||
|
if [ "$http_code" = "200" ]; then
|
||||||
|
touch "$path/$fileName"
|
||||||
|
echo "$response_body" > "$path/$fileName"
|
||||||
|
fi
|
||||||
|
echo "$(timestamp) [RESPONSE] code=$http_code" >> "$LOG_FILE"
|
||||||
|
|
||||||
|
# Delete old files (files older than configured period)
|
||||||
|
find $path ! -type d -mmin +$EVO_STORE_PERIOD_MINUTES -delete
|
||||||
|
}
|
||||||
|
|
||||||
|
# Setup logging function
|
||||||
|
setup_logging() {
|
||||||
|
LOG_DIR="$ROOT_DIR/logs"
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
LOG_FILE="$LOG_DIR/$(date +%Y%m%d).log"
|
||||||
|
}
|
||||||
21
run/evo/get-groups.sh
Executable file
21
run/evo/get-groups.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
source $SCRIPT_DIR/constants.sh
|
||||||
|
source $SCRIPT_DIR/functions.sh
|
||||||
|
|
||||||
|
# Setup logging
|
||||||
|
setup_logging
|
||||||
|
|
||||||
|
# Trap signals to ensure proper cleanup
|
||||||
|
trap 'cleanup 1' HUP INT QUIT TERM
|
||||||
|
|
||||||
|
path=$EVO_GROUPS_PATH/$EVO_API_STORE_ID
|
||||||
|
printf -v fileName "$EVO_RESPONSE_FILE_NAME_FORMAT.$EVO_RESPONSE_FILE_NAME_EXT" -1
|
||||||
|
mkdir -p $path
|
||||||
|
|
||||||
|
# Handle request for groups
|
||||||
|
handle_request "groups" "$EVO_API_GET_GROUPS" "$path" "$fileName"
|
||||||
|
|
||||||
|
# Use the cleanup function instead of directly exiting
|
||||||
|
cleanup 0
|
||||||
21
run/evo/get-products.sh
Executable file
21
run/evo/get-products.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
source $SCRIPT_DIR/constants.sh
|
||||||
|
source $SCRIPT_DIR/functions.sh
|
||||||
|
|
||||||
|
# Setup logging
|
||||||
|
setup_logging
|
||||||
|
|
||||||
|
# Trap signals to ensure proper cleanup
|
||||||
|
trap 'cleanup 1' HUP INT QUIT TERM
|
||||||
|
|
||||||
|
path=$EVO_PRODUCTS_PATH/$EVO_API_STORE_ID
|
||||||
|
printf -v fileName "$EVO_RESPONSE_FILE_NAME_FORMAT.$EVO_RESPONSE_FILE_NAME_EXT" -1
|
||||||
|
mkdir -p $path
|
||||||
|
|
||||||
|
# Handle request for products
|
||||||
|
handle_request "products" "$EVO_API_GET_PRODUCTS" "$path" "$fileName"
|
||||||
|
|
||||||
|
# Use the cleanup function instead of directly exiting
|
||||||
|
cleanup 0
|
||||||
21
run/evo/get-stores.sh
Executable file
21
run/evo/get-stores.sh
Executable file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
source $SCRIPT_DIR/constants.sh
|
||||||
|
source $SCRIPT_DIR/functions.sh
|
||||||
|
|
||||||
|
# Setup logging
|
||||||
|
setup_logging
|
||||||
|
|
||||||
|
# Trap signals to ensure proper cleanup
|
||||||
|
trap 'cleanup 1' HUP INT QUIT TERM
|
||||||
|
|
||||||
|
path=$EVO_STORES_PATH/$EVO_API_STORE_ID
|
||||||
|
printf -v fileName "$EVO_RESPONSE_FILE_NAME_FORMAT.$EVO_RESPONSE_FILE_NAME_EXT" -1
|
||||||
|
mkdir -p $path
|
||||||
|
|
||||||
|
# Handle request for stores
|
||||||
|
handle_request "stores" "$EVO_API_GET_STORES" "$path" "$fileName"
|
||||||
|
|
||||||
|
# Use the cleanup function instead of directly exiting
|
||||||
|
cleanup 0
|
||||||
13
run/run.sh
Executable file
13
run/run.sh
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
|
||||||
|
$SCRIPT_DIR/evo/get-groups.sh
|
||||||
|
$SCRIPT_DIR/evo/get-products.sh
|
||||||
|
$SCRIPT_DIR/vk/get-albums.sh
|
||||||
|
$SCRIPT_DIR/vk/send-albums.sh
|
||||||
|
$SCRIPT_DIR/vk/get-albums.sh
|
||||||
|
$SCRIPT_DIR/vk/get-products.sh
|
||||||
|
$SCRIPT_DIR/vk/send-products.sh
|
||||||
|
$SCRIPT_DIR/vk/get-products.sh
|
||||||
|
$SCRIPT_DIR/vk/delete-products.sh
|
||||||
5
run/test.sh
Executable file
5
run/test.sh
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
|
||||||
|
echo "Test [OK]." >> $SCRIPT_DIR/test.res
|
||||||
37
run/vk/clear.sh
Executable file
37
run/vk/clear.sh
Executable file
@@ -0,0 +1,37 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# This script cleans all VK-related directories and logs
|
||||||
|
# It removes all files from categories, albums, products and logs directories
|
||||||
|
|
||||||
|
# Get the directory where this script is located
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
# Load constants and functions
|
||||||
|
source $SCRIPT_DIR/constants.sh
|
||||||
|
source $SCRIPT_DIR/functions.sh
|
||||||
|
|
||||||
|
# Initialize logging system
|
||||||
|
setup_logging
|
||||||
|
|
||||||
|
# Ensure we clean up properly even if script is interrupted
|
||||||
|
trap 'cleanup 1' HUP INT QUIT TERM
|
||||||
|
|
||||||
|
# Begin cleanup process
|
||||||
|
echo "$(timestamp) [INFO] Starting cleanup process" >> "$LOG_FILE"
|
||||||
|
|
||||||
|
# Clean VK content directories
|
||||||
|
echo "$(timestamp) [INFO] Cleaning VK directories" >> "$LOG_FILE"
|
||||||
|
# Remove category files
|
||||||
|
echo "$(timestamp) [INFO] Removing category files" >> "$LOG_FILE"
|
||||||
|
echo "rm -f $VK_CATEGORIES_PATH/*" && rm -rf $VK_CATEGORIES_PATH/*
|
||||||
|
# Remove album files
|
||||||
|
echo "$(timestamp) [INFO] Removing album files" >> "$LOG_FILE"
|
||||||
|
echo "rm -f $VK_ALBUMS_PATH/*" && rm -rf $VK_ALBUMS_PATH/*
|
||||||
|
# Remove product files
|
||||||
|
echo "$(timestamp) [INFO] Removing product files" >> "$LOG_FILE"
|
||||||
|
echo "rm -f $VK_PRODUCTS_PATH/*" && rm -rf $VK_PRODUCTS_PATH/*
|
||||||
|
# Clean logs directory
|
||||||
|
echo "$(timestamp) [INFO] Cleaning logs directory" >> "$LOG_FILE"
|
||||||
|
echo "rm -f $LOG_DIR/*" && rm -rf $LOG_DIR/*
|
||||||
|
|
||||||
|
echo "$(timestamp) [INFO] Cleanup completed successfully" >> "$LOG_FILE"
|
||||||
|
cleanup 0
|
||||||
30
run/vk/constants.sh
Executable file
30
run/vk/constants.sh
Executable file
@@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
ROOT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
ROOT_DIR+='/../..'
|
||||||
|
|
||||||
|
VK_STORE_PERIOD_MINUTES=120
|
||||||
|
VK_API_CONTENT_TYPE_MULTIPART="multipart/form-data"
|
||||||
|
VK_API_HOST="https://api.vk.ru/method"
|
||||||
|
VK_API_USER_TOKEN=`cat "$ROOT_DIR/vk/api.credentials.user_token"`
|
||||||
|
VK_API_VERSION="5.199"
|
||||||
|
VK_API_ADD_PRODUCT="$VK_API_HOST/market.add?v=$VK_API_VERSION"
|
||||||
|
VK_API_EDIT_PRODUCT="$VK_API_HOST/market.edit?v=$VK_API_VERSION"
|
||||||
|
VK_API_ADD_PRODUCT_TO_ALBUM="$VK_API_HOST/market.addToAlbum?v=$VK_API_VERSION"
|
||||||
|
VK_API_ADD_ALBUM="$VK_API_HOST/market.addAlbum?v=$VK_API_VERSION"
|
||||||
|
VK_API_GET_CATEGORIES="$VK_API_HOST/market.getCategories?v=$VK_API_VERSION"
|
||||||
|
VK_API_GET_ALBUMS="$VK_API_HOST/market.getAlbums?v=$VK_API_VERSION"
|
||||||
|
VK_API_GET_PRODUCTS="$VK_API_HOST/market.get?v=$VK_API_VERSION"
|
||||||
|
VK_API_GROUP_ID=`cat "$ROOT_DIR/vk/api.credentials.group_id"`
|
||||||
|
VK_API_PARAM_OWNER_ID="-$VK_API_GROUP_ID"
|
||||||
|
VK_API_DELETE_PRODUCT="$VK_API_HOST/market.delete?v=$VK_API_VERSION"
|
||||||
|
VK_CATEGORIES_PATH="$ROOT_DIR/vk/categories"
|
||||||
|
VK_ALBUMS_PATH="$ROOT_DIR/vk/albums"
|
||||||
|
VK_PRODUCTS_PATH="$ROOT_DIR/vk/products"
|
||||||
|
VK_RESPONSE_FILE_NAME_FORMAT="%(%Y-%m-%d_%H:%M:%S)T"
|
||||||
|
VK_RESPONSE_FILE_NAME_EXT="json"
|
||||||
|
VK_API_CATEGORY_ID="40932"
|
||||||
|
VK_STOCK_AMOUNT=1000
|
||||||
|
VK_API_GET_PHOTO_UPLOAD_URL="$VK_API_HOST/market.getProductPhotoUploadServer?v=$VK_API_VERSION"
|
||||||
|
VK_API_PHOTO_PATH="$ROOT_DIR/5393364294319597854.png"
|
||||||
|
VK_API_UPLOAD_PHOTO_URL="$VK_API_HOST/market.saveProductPhoto"
|
||||||
92
run/vk/delete-products.sh
Executable file
92
run/vk/delete-products.sh
Executable file
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
# Delete products from vk which were deleted from evo.
|
||||||
|
# loop across vk products.
|
||||||
|
|
||||||
|
vkPath=$VK_PRODUCTS_PATH/$VK_API_GROUP_ID
|
||||||
|
vkFileName=`ls $vkPath -Art | tail -1`
|
||||||
|
vkFilePath=$vkPath/$vkFileName
|
||||||
|
|
||||||
|
evoPath=$EVO_PRODUCTS_PATH/$EVO_API_STORE_ID
|
||||||
|
evoFileName=`ls $evoPath -Art | tail -1`
|
||||||
|
evoFilePath=$evoPath/$evoFileName
|
||||||
|
|
||||||
|
hasEvoItems=`yq '. | has("items")' $evoFilePath`
|
||||||
|
if ! $hasEvoItems; then
|
||||||
|
cleanup 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Build associative array of EVO product names (transformed)
|
||||||
|
declare -A evoNames
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if [[ -n "$line" ]]; then
|
||||||
|
item_name=$(echo "$line" | yq -r '.name')
|
||||||
|
if [[ -n "$item_name" && "$item_name" != "null" ]]; then
|
||||||
|
transformed_name=$(echo "$item_name" | xargs)
|
||||||
|
transformed_name="${transformed_name//;/,}"
|
||||||
|
evoNames["$transformed_name"]=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < <(yq -o=j -I=0 '.items[]' $evoFilePath)
|
||||||
|
|
||||||
|
# Build associative array of VK items by name (transformed)
|
||||||
|
declare -A vkItemsByName
|
||||||
|
readarray vkItems < <(yq -o=j -I=0 '.response.items[]' $vkFilePath )
|
||||||
|
for vkItem in "${vkItems[@]}"; do
|
||||||
|
vkItemName=$(echo $vkItem | yq .title | xargs)
|
||||||
|
vkItemName="${vkItemName//;/,}"
|
||||||
|
vkItemId=$(echo $vkItem | yq .id)
|
||||||
|
# Store VK item IDs by name (append to comma-separated list)
|
||||||
|
if [[ -n "${vkItemsByName[$vkItemName]}" ]]; then
|
||||||
|
vkItemsByName[$vkItemName]="${vkItemsByName[$vkItemName]},$vkItemId"
|
||||||
|
else
|
||||||
|
vkItemsByName[$vkItemName]="$vkItemId"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# For each VK name, check if it exists in EVO
|
||||||
|
for vkName in "${!vkItemsByName[@]}"; do
|
||||||
|
IFS=',' read -ra ids <<< "${vkItemsByName[$vkName]}"
|
||||||
|
if [[ -n "${evoNames[$vkName]}" ]]; then
|
||||||
|
# If multiple VK items for this name, keep the oldest (first), delete the rest
|
||||||
|
if (( ${#ids[@]} > 1 )); then
|
||||||
|
for ((i=1; i<${#ids[@]}; i++)); do
|
||||||
|
vkItemId="${ids[$i]}"
|
||||||
|
echo "$(timestamp) [REQUEST] Deleting duplicate product: $vkName (id=$vkItemId)" >> "$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=$vkItemId \
|
||||||
|
$VK_API_DELETE_PRODUCT)
|
||||||
|
http_code=${response: -3}
|
||||||
|
response_body=${response:0:-3}
|
||||||
|
echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# If VK name not in EVO, delete all VK items for this name
|
||||||
|
for vkItemId in "${ids[@]}"; do
|
||||||
|
echo "$(timestamp) [REQUEST] Deleting product not in EVO: $vkName (id=$vkItemId)" >> "$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=$vkItemId \
|
||||||
|
$VK_API_DELETE_PRODUCT)
|
||||||
|
http_code=${response: -3}
|
||||||
|
response_body=${response:0:-3}
|
||||||
|
echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE"
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Use the cleanup function instead of directly exiting
|
||||||
|
cleanup 0
|
||||||
52
run/vk/functions.sh
Executable file
52
run/vk/functions.sh
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
# Setup logging
|
||||||
|
function setup_logging() {
|
||||||
|
LOG_DIR="$ROOT_DIR/logs"
|
||||||
|
mkdir -p "$LOG_DIR"
|
||||||
|
SCRIPT_NAME=$(basename "${BASH_SOURCE[0]}" .sh)
|
||||||
|
LOG_FILE="$LOG_DIR/$(date +%Y%m%d).log"
|
||||||
|
}
|
||||||
|
|
||||||
|
function timestamp() {
|
||||||
|
date "+%Y-%m-%d %H:%M:%S"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to handle cleanup and exit
|
||||||
|
function cleanup() {
|
||||||
|
# Kill all child processes of this script
|
||||||
|
pkill -P $$
|
||||||
|
exit $1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to handle requests and responses
|
||||||
|
function handle_vk_request() {
|
||||||
|
local request_name=$1
|
||||||
|
local request_url=$2
|
||||||
|
local path=$3
|
||||||
|
local fileName=$4
|
||||||
|
local additional_params=$5
|
||||||
|
local debug_response=${6:-true}
|
||||||
|
|
||||||
|
echo "$(timestamp) [REQUEST] Getting $request_name" >> "$LOG_FILE"
|
||||||
|
response=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $VK_API_USER_TOKEN" \
|
||||||
|
-X GET \
|
||||||
|
"$request_url$additional_params")
|
||||||
|
http_code=${response: -3}
|
||||||
|
response_body=${response:0:-3}
|
||||||
|
if [ "$http_code" = "200" ]; then
|
||||||
|
if ! echo "$response_body" | jq -e 'has("error")' > /dev/null; then
|
||||||
|
touch "$path/$fileName"
|
||||||
|
echo "$response_body" > "$path/$fileName"
|
||||||
|
else
|
||||||
|
error_msg=$(echo "$response_body" | jq -r '.error.error_msg')
|
||||||
|
echo "$(timestamp) [ERROR] $error_msg" >> "$LOG_FILE"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$debug_response" = true ]; then
|
||||||
|
echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE"
|
||||||
|
else
|
||||||
|
echo "$(timestamp) [RESPONSE] code=$http_code" >> "$LOG_FILE"
|
||||||
|
fi
|
||||||
|
}
|
||||||
24
run/vk/get-albums.sh
Executable file
24
run/vk/get-albums.sh
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
source $SCRIPT_DIR/constants.sh
|
||||||
|
source $SCRIPT_DIR/functions.sh
|
||||||
|
|
||||||
|
# Setup logging
|
||||||
|
setup_logging
|
||||||
|
|
||||||
|
# Trap signals to ensure proper cleanup
|
||||||
|
trap 'cleanup 1' HUP INT QUIT TERM
|
||||||
|
|
||||||
|
path=$VK_ALBUMS_PATH/$VK_API_GROUP_ID
|
||||||
|
mkdir -p $path
|
||||||
|
printf -v fileName "$VK_RESPONSE_FILE_NAME_FORMAT.$VK_RESPONSE_FILE_NAME_EXT" -1
|
||||||
|
|
||||||
|
# Handle request for albums
|
||||||
|
handle_vk_request "albums list" "$VK_API_GET_ALBUMS" "$path" "$fileName" "&owner_id=$VK_API_PARAM_OWNER_ID" false
|
||||||
|
|
||||||
|
# Clean up old files
|
||||||
|
find $path ! -type d -mmin +$VK_STORE_PERIOD_MINUTES -delete
|
||||||
|
|
||||||
|
# Use the cleanup function instead of directly exiting
|
||||||
|
cleanup 0
|
||||||
24
run/vk/get-categories.sh
Executable file
24
run/vk/get-categories.sh
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
source $SCRIPT_DIR/constants.sh
|
||||||
|
source $SCRIPT_DIR/functions.sh
|
||||||
|
|
||||||
|
# Setup logging
|
||||||
|
setup_logging
|
||||||
|
|
||||||
|
# Trap signals to ensure proper cleanup
|
||||||
|
trap 'cleanup 1' HUP INT QUIT TERM
|
||||||
|
|
||||||
|
path=$VK_CATEGORIES_PATH/$VK_API_GROUP_ID
|
||||||
|
mkdir -p $path
|
||||||
|
printf -v fileName "$VK_RESPONSE_FILE_NAME_FORMAT.$VK_RESPONSE_FILE_NAME_EXT" -1
|
||||||
|
|
||||||
|
# Handle request for categories
|
||||||
|
handle_vk_request "categories list" "$VK_API_GET_CATEGORIES" "$path" "$fileName" "" false
|
||||||
|
|
||||||
|
# Clean up old files
|
||||||
|
find $path ! -type d -mmin +$VK_STORE_PERIOD_MINUTES -delete
|
||||||
|
|
||||||
|
# Use the cleanup function instead of directly exiting
|
||||||
|
cleanup 0
|
||||||
24
run/vk/get-products.sh
Executable file
24
run/vk/get-products.sh
Executable file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
|
||||||
|
source $SCRIPT_DIR/constants.sh
|
||||||
|
source $SCRIPT_DIR/functions.sh
|
||||||
|
|
||||||
|
# Setup logging
|
||||||
|
setup_logging
|
||||||
|
|
||||||
|
# Trap signals to ensure proper cleanup
|
||||||
|
trap 'cleanup 1' HUP INT QUIT TERM
|
||||||
|
|
||||||
|
path=$VK_PRODUCTS_PATH/$VK_API_GROUP_ID
|
||||||
|
mkdir -p $path
|
||||||
|
printf -v fileName "$VK_RESPONSE_FILE_NAME_FORMAT.$VK_RESPONSE_FILE_NAME_EXT" -1
|
||||||
|
|
||||||
|
# Handle request for products
|
||||||
|
handle_vk_request "products list" "$VK_API_GET_PRODUCTS" "$path" "$fileName" "&owner_id=$VK_API_PARAM_OWNER_ID&extended=1&with_disabled=1&count=200" false
|
||||||
|
|
||||||
|
# Clean up old files
|
||||||
|
find $path ! -type d -mmin +$VK_STORE_PERIOD_MINUTES -delete
|
||||||
|
|
||||||
|
# Use the cleanup function instead of directly exiting
|
||||||
|
cleanup 0
|
||||||
47
run/vk/send-albums.sh
Executable file
47
run/vk/send-albums.sh
Executable file
@@ -0,0 +1,47 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
evoPath=$EVO_GROUPS_PATH/$EVO_API_STORE_ID
|
||||||
|
evoFileName=`ls $evoPath -Art | tail -1`
|
||||||
|
evoFilePath=$evoPath/$evoFileName
|
||||||
|
vkPath=$VK_ALBUMS_PATH/$VK_API_GROUP_ID
|
||||||
|
vkFileName=`ls $vkPath -Art | tail -1`
|
||||||
|
vkFilePath=$vkPath/$vkFileName
|
||||||
|
|
||||||
|
# Load whitelist
|
||||||
|
readarray -t whitelist < "$ROOT_DIR/vk/whitelist"
|
||||||
|
|
||||||
|
# Filter items by whitelist
|
||||||
|
readarray items < <(yq -o=j -I=0 ".items[]" $evoFilePath)
|
||||||
|
|
||||||
|
for item in "${items[@]}"; do
|
||||||
|
evoTitle=`echo $item | yq .name`
|
||||||
|
# Check if group is whitelisted
|
||||||
|
if [[ ! " ${whitelist[@]} " =~ " ${evoTitle} " ]]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
found=`evoTitle="$evoTitle" yq '.response.items[] | select(.title==strenv(evoTitle))' $vkFilePath`
|
||||||
|
if [[ ! -n "$found" ]]; then
|
||||||
|
echo "$(timestamp) [REQUEST] Creating album: $evoTitle" >> "$LOG_FILE"
|
||||||
|
response=$(curl -s -w "%{http_code}" -H "Authorization: Bearer $VK_API_USER_TOKEN" \
|
||||||
|
-F owner_id=$VK_API_PARAM_OWNER_ID \
|
||||||
|
-F title="$evoTitle" \
|
||||||
|
$VK_API_ADD_ALBUM)
|
||||||
|
http_code=${response: -3}
|
||||||
|
response_body=${response:0:-3}
|
||||||
|
echo "$(timestamp) [RESPONSE] code=$http_code body=$response_body" >> "$LOG_FILE"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Use the cleanup function instead of directly exiting
|
||||||
|
cleanup 0
|
||||||
257
run/vk/send-products.sh
Executable file
257
run/vk/send-products.sh
Executable file
@@ -0,0 +1,257 @@
|
|||||||
|
#!/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
|
||||||
10
vk/whitelist-old
Normal file
10
vk/whitelist-old
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Белый
|
||||||
|
Желтый
|
||||||
|
Зеленый
|
||||||
|
Красный
|
||||||
|
Улуны светлые
|
||||||
|
Улуны тёмные
|
||||||
|
Чай с добавками
|
||||||
|
Чёрный
|
||||||
|
Шупуэр
|
||||||
|
Шэнпуэр
|
||||||
Reference in New Issue
Block a user