Sync project structure and apply feature updates
- Move files from remote_copy/ to root (proper project structure) - Add Docker setup: Dockerfile, docker-compose.yml with volume mounts - Auto-reply: fix skip logic (only text field, not pros/cons) - Auto-reply: fix _paginate to handle cooldown gracefully mid-pagination - Auto-reply: fix fetch timestamp not saved on API error (infinite retry loop) - Auto-reply: reduce EMPTY_REMAINING_FALLBACK from 600s to 150s default - UI: add auto-reply queue display with article number (nm_id) - UI: replace button with CSS tumbler toggle for auto-reply - UI: add review_created_at and review_id columns to journal - UI: add skipped/sent/error status colors to journal Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,61 @@
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
import requests
|
||||
from dotenv import load_dotenv
|
||||
|
||||
BASE_DIR = Path('/home/sites/wild')
|
||||
load_dotenv(BASE_DIR / '.env')
|
||||
|
||||
token = (os.getenv('WB_API_TOKEN') or '').strip()
|
||||
if not token:
|
||||
raise SystemExit('WB_API_TOKEN not found in /home/sites/wild/.env')
|
||||
|
||||
url = 'https://feedbacks-api.wildberries.ru/api/v1/feedbacks'
|
||||
headers = {'Authorization': f'Bearer {token}'}
|
||||
params = {'isAnswered': 'true', 'skip': 0, 'take': 300}
|
||||
resp = requests.get(url, headers=headers, params=params, timeout=20)
|
||||
resp.raise_for_status()
|
||||
payload = resp.json()
|
||||
items = (payload.get('data') or {}).get('feedbacks') or []
|
||||
|
||||
filtered = []
|
||||
for item in items:
|
||||
rating = item.get('productValuation') or 0
|
||||
if rating not in (4, 5):
|
||||
continue
|
||||
ans = item.get('answer')
|
||||
if isinstance(ans, dict):
|
||||
ans_text = (ans.get('text') or '').strip()
|
||||
else:
|
||||
ans_text = (ans or '').strip()
|
||||
if not ans_text:
|
||||
continue
|
||||
filtered.append({
|
||||
'createdDate': item.get('createdDate') or '',
|
||||
'id': item.get('id') or '',
|
||||
'rating': rating,
|
||||
'productName': ((item.get('productDetails') or {}).get('productName') or ''),
|
||||
'userName': item.get('userName') or '',
|
||||
'answer': ans_text,
|
||||
})
|
||||
|
||||
filtered.sort(key=lambda x: x['createdDate'], reverse=True)
|
||||
last100 = filtered[:100]
|
||||
|
||||
out_json = BASE_DIR / 'last_100_answers_4_5.json'
|
||||
out_txt = BASE_DIR / 'last_100_answers_4_5.txt'
|
||||
out_json.write_text(json.dumps(last100, ensure_ascii=False, indent=2), encoding='utf-8')
|
||||
|
||||
lines = []
|
||||
for i, row in enumerate(last100, 1):
|
||||
lines.append(
|
||||
f"{i}. {row['createdDate']} | {row['rating']}★ | {row['productName']} | {row['userName']} | {row['answer']}"
|
||||
)
|
||||
out_txt.write_text('\n'.join(lines), encoding='utf-8')
|
||||
|
||||
print(f'exported={len(last100)}')
|
||||
print(out_json)
|
||||
print(out_txt)
|
||||
Reference in New Issue
Block a user