sms
This commit is contained in:
1 parent
250cdbab7f
commit
5c6069c3ef
87 files changed
+29209
-3697
No files matched your search
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# اجرای کامل کتیبه در محیط توسعهٔ محلی — بدون Docker.
|
||||
#
|
||||
# چهار سرویس را با هم بالا میآورد:
|
||||
# web → runserver روی 0.0.0.0:8000 (طبق قرارداد پروژه، برای دسترسی از LAN)
|
||||
# worker → تخلیهٔ صف پیامک (sms_worker)
|
||||
# scanner → اسکن دورهای و صفکردن یادآوریها (sms_scan --loop)
|
||||
# delivery → استعلام وضعیت تحویل پیامکها (sms_delivery --sleep 30)
|
||||
#
|
||||
# استفاده:
|
||||
# ./run.sh همه چیز
|
||||
# ./run.sh --no-scan بدون اسکنر
|
||||
# ./run.sh --no-worker بدون worker پیامک
|
||||
# ./run.sh --no-delivery بدون استعلام دلیوری
|
||||
# ./run.sh --no-web فقط سرویسهای پسزمینه
|
||||
# ./run.sh --no-migrate مایگریشن اجرا نشود
|
||||
# ./run.sh --reload runserver با auto-reload (دو پروسه، فقط برای کدنویسی)
|
||||
# ./run.sh -f پس از بالا آمدن، لاگها را دنبال کن (Ctrl+C فقط دنبالکردن را قطع میکند)
|
||||
# ./run.sh -h راهنما
|
||||
#
|
||||
# لاگها و فایلهای PID در .run/ قرار میگیرند. برای توقف: ./stop.sh
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$(readlink -f "$0")")"
|
||||
|
||||
RUN_DIR=".run"
|
||||
WEB_PORT="8000"
|
||||
WEB_HOST="0.0.0.0"
|
||||
WORKER_SLEEP="${WORKER_SLEEP:-3}"
|
||||
SCAN_INTERVAL="${SCAN_INTERVAL:-300}"
|
||||
|
||||
START_WEB=1
|
||||
START_WORKER=1
|
||||
START_SCAN=1
|
||||
START_DELIVERY=1
|
||||
DO_MIGRATE=1
|
||||
RELOAD=0
|
||||
FOLLOW=0
|
||||
|
||||
usage() {
|
||||
sed -n '3,20p' "$0" | sed 's/^# \{0,1\}//'
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
--no-web) START_WEB=0 ;;
|
||||
--no-worker) START_WORKER=0 ;;
|
||||
--no-scan) START_SCAN=0 ;;
|
||||
--no-delivery) START_DELIVERY=0 ;;
|
||||
--no-migrate) DO_MIGRATE=0 ;;
|
||||
--reload) RELOAD=1 ;;
|
||||
-f|--follow|--logs) FOLLOW=1 ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "گزینهٔ ناشناخته: $1" >&2; echo; usage; exit 2 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ۱) پیدا کردن مفسر پایتون از venv مخزن (هرگز پایتون سیستم)
|
||||
# ---------------------------------------------------------------------------
|
||||
PY=""
|
||||
for candidate in ".venv/Scripts/python.exe" ".venv/bin/python" ".venv/bin/python3"; do
|
||||
if [ -x "$candidate" ]; then PY="$candidate"; break; fi
|
||||
done
|
||||
if [ -z "$PY" ]; then
|
||||
echo "خطا: مفسر پایتون در .venv پیدا نشد." >&2
|
||||
echo " ابتدا محیط مجازی مخزن را بساز/فعال کن (.venv)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p "$RUN_DIR"
|
||||
|
||||
echo "==> کتیبه — اجرای محلی (dev)"
|
||||
echo " python : $PY"
|
||||
echo " run dir : $RUN_DIR/"
|
||||
[ "$START_WEB" = "1" ] && echo " web : http://$WEB_HOST:$WEB_PORT"
|
||||
[ "$START_WORKER" = "1" ] && echo " worker : sms_worker --sleep $WORKER_SLEEP"
|
||||
[ "$START_SCAN" = "1" ] && echo " scanner : sms_scan --loop --interval $SCAN_INTERVAL"
|
||||
[ "$START_DELIVERY" = "1" ] && echo " delivery: sms_delivery --sleep 30"
|
||||
echo
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ۲) توقف نسخهٔ قبلی — جلوگیری از «database is locked» و پورت اشغال
|
||||
# ---------------------------------------------------------------------------
|
||||
echo "==> توقف نسخهٔ قبلی (اگر بالا باشد)"
|
||||
bash ./stop.sh --quiet || true
|
||||
echo
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ۳) مایگریشنها (idempotent)
|
||||
# ---------------------------------------------------------------------------
|
||||
if [ "$DO_MIGRATE" = "1" ]; then
|
||||
echo "==> اعمال مایگریشنها"
|
||||
"$PY" manage.py migrate --noinput
|
||||
echo
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ۴) بالا آوردن سرویسها
|
||||
# ---------------------------------------------------------------------------
|
||||
start_service() {
|
||||
local name="$1"; shift
|
||||
local log="$RUN_DIR/$name.log"
|
||||
local pidfile="$RUN_DIR/$name.pid"
|
||||
: > "$log"
|
||||
# -X utf8: حالت UTF-8 پایتون (PEP 540). روی ویندوز کنسول cp1252 است و بدون این،
|
||||
# نوشتن متن فارسی (مثلاً در provider کنسول پیامک) خطای 'charmap' میدهد.
|
||||
# دقت: PYTHONIOENCODING از طریق WSL interop به پروسهٔ ویندوزی منتقل نمیشود، ولی
|
||||
# آرگومان خط فرمان منتقل میشود؛ برای همین به -X utf8 تکیه میکنیم.
|
||||
PYTHONUNBUFFERED=1 PYTHONIOENCODING=utf-8 \
|
||||
nohup "$PY" -X utf8 -u manage.py "$@" >>"$log" 2>&1 &
|
||||
echo $! > "$pidfile"
|
||||
printf ' %-8s pid %s\n' "$name" "$(cat "$pidfile")"
|
||||
}
|
||||
|
||||
echo "==> بالا آوردن سرویسها"
|
||||
if [ "$START_WEB" = "1" ]; then
|
||||
if [ "$RELOAD" = "1" ]; then
|
||||
start_service web runserver "$WEB_HOST:$WEB_PORT"
|
||||
else
|
||||
start_service web runserver "$WEB_HOST:$WEB_PORT" --noreload
|
||||
fi
|
||||
fi
|
||||
[ "$START_WORKER" = "1" ] && start_service worker sms_worker --sleep "$WORKER_SLEEP"
|
||||
[ "$START_SCAN" = "1" ] && start_service scanner sms_scan --loop --interval "$SCAN_INTERVAL"
|
||||
[ "$START_DELIVERY" = "1" ] && start_service delivery sms_delivery --sleep 30
|
||||
echo
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ۵) تأیید سلامت وبسرور (فقط اگر درخواست شده باشد)
|
||||
# ---------------------------------------------------------------------------
|
||||
if [ "$START_WEB" = "1" ]; then
|
||||
echo "==> بررسی سلامت وبسرور"
|
||||
healthy=0
|
||||
for _ in $(seq 1 30); do
|
||||
# --noproxy: در این محیط یک پروکسی محلی (127.0.0.1:10808) هست و درخواست به
|
||||
# localhost را از خودش رد میکند و کد 503 میدهد؛ باید صریحاً دور زده شود.
|
||||
code="$(curl -s --noproxy '*' -o /dev/null -w '%{http_code}' \
|
||||
"http://127.0.0.1:$WEB_PORT/panel/p_login/" || true)"
|
||||
if [ "$code" = "200" ]; then healthy=1; break; fi
|
||||
sleep 1
|
||||
done
|
||||
if [ "$healthy" = "1" ]; then
|
||||
echo " http://127.0.0.1:$WEB_PORT/panel/p_login/ → HTTP 200"
|
||||
else
|
||||
echo " هشدار: وبسرور ظرف ۳۰ ثانیه پاسخ نداد؛ لاگ را ببین: $RUN_DIR/web.log" >&2
|
||||
fi
|
||||
echo
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ۶) هشدار ایمنی پیامک — جلوگیری از ارسال واقعی در حین توسعه
|
||||
# ---------------------------------------------------------------------------
|
||||
provider_line="$("$PY" - <<'PYEOF' 2>/dev/null || true
|
||||
import os, django
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "khatibi.settings")
|
||||
try:
|
||||
django.setup()
|
||||
from admin_panel.models import SMSProviderConfig
|
||||
c = SMSProviderConfig.load()
|
||||
print("%s|%s" % (c.provider, "on" if c.is_enabled else "off"))
|
||||
except Exception:
|
||||
print("unknown|unknown")
|
||||
PYEOF
|
||||
)"
|
||||
provider="${provider_line%%|*}"
|
||||
enabled="${provider_line##*|}"
|
||||
if [ "$enabled" = "on" ] && [ "$provider" != "console" ]; then
|
||||
echo "⚠️ هشدار: provider پیامک روی «$provider» و ارسال فعال است."
|
||||
echo " worker ممکن است پیامک واقعی بفرستد. برای تست محلی، از"
|
||||
echo " /panel/sms/settings آن را روی console بگذار."
|
||||
echo
|
||||
fi
|
||||
|
||||
echo "✅ راهاندازی تمام شد."
|
||||
echo " لاگها : $RUN_DIR/{web,worker,scanner,delivery}.log → tail -f $RUN_DIR/worker.log"
|
||||
echo " توقف : ./stop.sh"
|
||||
|
||||
if [ "$FOLLOW" = "1" ]; then
|
||||
echo
|
||||
echo "==> دنبالکردن لاگها (Ctrl+C فقط همین را قطع میکند؛ سرویسها بالا میمانند)"
|
||||
tail -n 0 -f "$RUN_DIR"/*.log
|
||||
fi
|
||||
Reference in new issue
Block a user