صدای شاعر · نسخهٔ آزمایشی ۲.۰.۰ · Django و PostgreSQL

راهنمای نصب سرور و اندروید

مدیریت کتاب، چند اجرا، گالری ۲۰ عکس، تم‌های خواننده و پخش صوت رمزگذاری‌شده.

فایل‌های تحویل

فایلکاربرد
PoetVoice-Complete-Package.zipسرور Django، تنظیم PostgreSQL، نصاب، پنل آماده، سورس اندروید، ابزار انتقال اطلاعات و گزارش بررسی.
PoetVoice-Android-Test.apkفایل نصب واقعی و امضاشدهٔ اندروید؛ نسخهٔ ۲.۰.۰، شمارهٔ ساخت ۲۰۰.
PoetVoice-Setup-FA.htmlهمین راهنمای فارسی؛ بدون اینترنت در مرورگر باز می‌شود.

این بسته برای سرور مستقل شماست و هنوز روی دامنه یا VPS شما نصب نشده است. نصب تازه، کتاب خالی ایجاد می‌کند؛ شعر نمونهٔ سایت نمایشی در این بسته نیست. در این تحویل فقط اندروید آماده شده است؛ IPA و کلاینت آیفون سازگار با حفاظت نسخهٔ ۲ ارائه نشده‌اند.

مشخصات پیشنهادی سرور

موردپیشنهاد شروع
سیستم‌عاملUbuntu Server 24.04 LTS، ۶۴ بیتی، ترجیحاً سرور تازه با دسترسی sudo.
پردازنده و حافظه۲ هستهٔ مجازی و ۴ گیگابایت RAM. کارت گرافیک لازم نیست.
دیسکحداقل ۸۰ گیگابایت SSD؛ متناسب با صوت‌ها و عکس‌ها افزایش دهید. بکاپ خارج از سرور نگهداری شود.
شبکهIP عمومی، دامنهٔ اختصاصی مانند audio.example.com و ترافیک ماهانهٔ کافی.
پورت ورودیTCP 80 و 443؛ UDP 443 اختیاری برای HTTP/3. پورت PostgreSQL و پورت داخلی برنامه از اینترنت منتشر نمی‌شوند.
دسترسی خروجی نصبمخازن Ubuntu، Docker Hub، PyPI، DNS و سرویس صدور گواهی HTTPS.

این مشخصات برآورد اولیه است؛ آزمون بار انجام نشده است. هر اجرای پنج‌دقیقه‌ای با کیفیت ۱۲۸ کیلوبیت بر ثانیه تقریباً ۴٫۸ مگابایت است. هزار شعر با دو اجرا حدود ۹٫۶ گیگابایت صوت دارد؛ تصاویر و بکاپ جدا محاسبه شوند.

اجزای بسته: Django 5.2.17 LTS، PostgreSQL 18، Python 3.13، Gunicorn و Caddy. وابستگی‌های Python با نسخه و هش قفل شده‌اند. PostgreSQL و Caddy هنگام نصب از شاخهٔ اصلی مشخص‌شده، وصله‌های جدید را می‌گیرند. نسخه‌های پشتیبانی‌شدهٔ Django، تصویر رسمی PostgreSQL، پشتیبانی Ubuntu

نصب تازه

  1. رکورد A دامنه را به IPv4 سرور وصل کنید. اگر AAAA دارید، IPv6 سرور باید قابل دسترس باشد. پورت‌های ۸۰ و ۴۴۳ آزاد باشند؛ سرویس دیگری روی آن‌ها اجرا نشود.
  2. فایل ZIP را به سرور منتقل و در پوشهٔ نصب استخراج کنید. در صورت نبود فرمان unzip، آن را از مخزن Ubuntu نصب کنید.
unzip PoetVoice-Complete-Package.zip
cd PoetVoice/server
sudo bash install.sh

نصاب Docker، Compose و Python را در صورت نیاز نصب می‌کند؛ سپس دامنه را بدون https:// می‌پرسد، رمزهای تصادفی سرور و کلید رمزگذاری را می‌سازد، پایگاه PostgreSQL را آماده و مهاجرت‌های Django را اجرا می‌کند. سپس نام کاربری مدیر و رمز آن را وارد کنید. رمز حداقل ۱۲ نویسه باشد و ساده یا کاملاً عددی نباشد. هنگام تایپ رمز، چیزی نمایش داده نمی‌شود.

Caddy گواهی HTTPS را خودکار دریافت می‌کند. حساب مدیر در https://YOUR-DOMAIN/admin وارد می‌شود. آدرس مورد نیاز گوشی فقط https://YOUR-DOMAIN است؛ مسیر /admin را در برنامه ننویسید.

sudo docker compose ps
sudo docker compose logs --tail 60 api proxy
curl --fail https://YOUR-DOMAIN/health

پاسخ سلامت باید {"status":"ok"} باشد. حساب یا رمز پیش‌فرض عمومی در بسته نیست. فونت فارسی و نقش تذهیب پنل، روی خود سرور قرار دارند. اگر نصب بستهٔ docker-compose-v2 روی Ubuntu حداقلی موفق نشد، فعال‌بودن مخزن Universe و نتیجهٔ docker compose version را بررسی کنید.

فایل secrets/media_master_key کلید اصلی صوت‌هاست. آن را حذف یا دوباره تولید نکنید. فایل .env نیز رمزهای سرور را دارد. هر دو باید همراه داده‌ها، به‌صورت خصوصی بکاپ گرفته شوند.

انتقال از نسخهٔ ۱.۲ یا قدیمی‌تر

نسخهٔ جدید را در پوشه‌ای جدا نصب کنید. فایل‌های جدید را روی پوشهٔ دادهٔ قبلی نریزید. از پوشهٔ سرور قدیمی ابتدا بکاپ بگیرید و سپس سرویس‌های آن را متوقف کنید؛ توقف، پورت‌های HTTPS را نیز برای سرور جدید آزاد می‌کند:

# Run in the OLD server directory:
sudo bash backup.sh
sudo docker compose stop

از پوشهٔ سرور جدید، مسیر واقعی پوشهٔ دادهٔ قبلی را جایگزین کنید:

# Run in the NEW server directory:
sudo bash install.sh --import /ABSOLUTE/PATH/TO/OLD/server/data

پوشهٔ مبدأ باید فایل poetvoice.sqlite3 و پوشهٔ media را داشته باشد. مبدأ فقط خوانده می‌شود؛ مقصد باید خالی باشد. ابزار، حساب‌ها، رمزهای قبلی، وضعیت کدهای فعال‌سازی، شعرها، شناسه‌ها، QRهای ثابت، چند اجرا، تصاویر و زمان‌بندی‌ها را منتقل می‌کند و صوت‌ها را برای مقصد رمزگذاری می‌کند. رمز حساب پس از اولین ورود، به قالب Django ارتقا می‌یابد.

دامنهٔ قبلی را می‌توانید نگه دارید. خوانندگان باید APK نسخهٔ ۲ را نصب و دوباره وارد حساب شوند. ثبت دوبارهٔ کد کتاب برای حسابی که فعال بوده لازم نیست. اپ‌های نسخهٔ ۱ و پروژهٔ قدیمی آیفون، پخش محافظت‌شدهٔ این سرور را پشتیبانی نمی‌کنند. بعد از انتقال، سرور قدیمی خاموش بماند و بکاپ آن خصوصی نگهداری شود.

اگر انتقال خطا داد، مبدأ دست‌نخورده باقی می‌ماند. علت معمول، فایل گم‌شده یا صوت معیوب است. قبل از تکرار، پیام را بررسی کنید؛ برای مقصدی که قبلاً اطلاعات دارد، مهاجرت مجدد مجاز نیست.

ثبت کتاب، شعر و اجراها

  1. وارد پنل مدیر شوید. نام شعر را بنویسید و QR چاپ‌شده را با دوربین بخوانید یا تصویر آن را بارگذاری کنید. دسترسی دوربین به HTTPS و اجازهٔ مرورگر نیاز دارد.
  2. تصویر مرتبط، عکس صفحهٔ کتاب و فایل صوتی را بارگذاری کنید. برای سازگاری، MP3 استاندارد انتخاب کنید. عکس صفحهٔ کتاب فقط در پنل مدیریت است.
  3. برای همان شعر، هر تعداد اجرای لازم اضافه و نام گوینده را ثبت کنید. همهٔ اجراها زیر همان QR قرار می‌گیرند. تغییر فایل صوت یا افزودن اجرا، QR چاپ‌شده را تغییر نمی‌دهد.
  4. در معرفی کتاب و شاعر، نام و متن معرفی را ثبت کنید.
  5. از بخش کدهای فعال‌سازی، برای هر نسخهٔ چاپی یک کد بسازید. هر بار ۱ تا ۱۰۰ کد قابل ایجاد است و کدها فقط همان بار نشان داده می‌شوند. فایل آن‌ها را خصوصی نگه دارید و هر کد را داخل یک نسخهٔ کتاب قرار دهید.

کد فعال‌سازی حساب با QR هر شعر متفاوت است. هر حساب حداکثر دو دستگاه فعال دارد. حداکثر حجم هر صوت ۶۴ MiB، هر عکس ۱۲ MiB و تصویر QR چهار MiB است. PNG، JPEG و WebP پذیرفته می‌شوند. فایل تصویر با Pillow و صوت با ffprobe بررسی می‌شود؛ تبدیل قالب یا کاهش حجم خودکار انجام نمی‌شود.

گالری ۲۰ عکس و زمان‌بندی

برای هر شعر تا ۲۰ عکس قرار دهید. در حالت تصادفی، مدت هر عکس را بین ۱ تا ۳۶۰۰ ثانیه تعیین کنید؛ پیش‌فرض ۱۰ ثانیه است. زمان مکث حساب نمی‌شود و تغییر سرعت صوت، مدت واقعی نمایش عکس را عوض نمی‌کند.

در حالت هماهنگ با صوت، اجرا را انتخاب کنید، عکس را مشخص کنید و زمان آن را ثبت کنید؛ مثلاً عکس خورشید در ثانیهٔ ۳۵. زمان هر اجرا جداست و برای اجرای دیگر می‌تواند ۴۲ ثانیه باشد. هر عکس تا زمان عکس بعدی باقی می‌ماند؛ پیش از اولین زمان، تصویر اول نمایش داده می‌شود. جلو و عقب بردن صوت، عکس همان لحظه را انتخاب می‌کند. حداکثر ۵۰۰ زمان برای هر شعر قابل ثبت است. دریافت‌نشدن تصویر در اینترنت ضعیف می‌تواند نمایش آن را عقب بیندازد.

نصب APK و اتصال گوشی

  1. فایل PoetVoice-Android-Test.apk را روی Android 8 یا بالاتر باز کنید و در صورت درخواست سیستم، اجازهٔ نصب از برنامهٔ دریافت‌کننده را بدهید. برای به‌روزرسانی آزمایشی قبلی، آن را روی همان برنامه نصب کنید؛ امضای آزمایشی ثابت مانده است.
  2. Android System WebView را به‌روز نگه دارید. در اجرای اول، آدرس HTTPS سرور مستقل خودتان را وارد کنید. آدرس سایت نمایشی، API این بسته نیست.
  3. حساب خواننده بسازید یا وارد حساب قبلی شوید. حساب مدیر برای ورود به اپ خواننده نیست. در نصب تازه، کد فعال‌سازی نسخهٔ کتاب را وارد کنید.
  4. اسکن QR را بزنید، اجازهٔ دوربین بدهید و QR کنار شعر را بخوانید. اجرا شروع می‌شود؛ برای صدای دیگر، گزینهٔ انتخاب اجرا را بزنید.

سرعت با چرخ اسکرولی، بلندی صدا با کنترل عمودی و زمان با نوار افقی تنظیم می‌شود. دکمه‌های جلو و عقب، ده ثانیه جابه‌جا می‌کنند. موج روی تصویر، انیمیشن همراه پخش است و تحلیل طیف واقعی صوت نیست. پخش هنگام خروج از برنامه یا قفل‌شدن گوشی متوقف می‌شود.

در تنظیمات، ظاهر ساده یا یکی از تم‌های عارفانه، شاعرانه، طبیعت، آرامش، عاشقانه، حماسی و تذهیب را انتخاب کنید. فرم و سایهٔ دکمه‌ها هم تغییر می‌کند؛ دکمهٔ برجسته هنگام فشار به داخل می‌رود. روشن، تاریک یا هماهنگ با گوشی مستقل از تم انتخاب می‌شود و روی همان دستگاه ذخیره می‌ماند.

APK با کلید آزمایشی امضا شده است. برای توزیع عمومی، نسخهٔ نهایی باید با کلید خصوصی مالک ساخته شود. کلید آزمایشی داخل سورس قرار دارد و کلید محرمانهٔ انتشار نیست. جزئیات ساخت در mobile/android/README.md آمده است.

حفاظت ضد دانلود چه کاری انجام می‌دهد؟

این حفاظت، Widevine یا FairPlay DRM نیست و جلوگیری صددرصدی را تضمین نمی‌کند. رمزنگاری از الگوریتم‌های استاندارد استفاده می‌کند، اما قالب انتقال برنامه اختصاصی است. کاربر دارای حساب معتبر با نرم‌افزار اختصاصی، ابزار تخصصی یا گوشی دستکاری‌شده ممکن است صوت را استخراج کند. محتوای قبلاً دریافت‌شده از راه دور پس گرفته نمی‌شود. ضبط با دستگاه دیگر نیز قابل جلوگیری نیست. تصاویر دارای مجوز موقت هستند، اما DRM ندارند. مدیر مالک محتوا می‌تواند در پنل صوت را پیش‌شنوی کند.

مشخصات دقیق در server/SECURITY-PROTOCOL.md است. DRM پلتفرمی به سرویس مجوز، بسته‌بندی محتوا و اتصال کلاینت نیاز دارد؛ در این تحویل، چنین سرویسی به‌عنوان فعال معرفی نشده است. مستندات Widevine، مستندات Android Keystore

پشتیبان‌گیری و مدیریت

از پوشهٔ سرور اجرا کنید:

sudo bash backup.sh

برنامه و سرویس نگهداری برای مدت کوتاهی متوقف می‌شوند؛ PostgreSQL dump، پوشهٔ فایل‌ها، کلید اصلی و تنظیمات داخل آرشیو خصوصی ذخیره و سرویس‌ها دوباره فعال می‌شوند. بکاپ را خارج از سرور نگه دارید. این فرمان، انتقال بکاپ به سرور دیگر یا پاک‌کردن نسخه‌های قدیمی را خودکار نمی‌کند؛ زمان‌بندی روزانه را مدیر سرور باید تنظیم کند.

تغییر رمز حساب و لغو تمام دستگاه‌های یک خواننده:

sudo docker compose exec api python manage.py changepassword USERNAME
sudo docker compose exec api python manage.py reset_devices READER_USERNAME

تغییر رمز خواننده، مجوزهای نشست قبلی را بی‌اعتبار می‌کند. برای آزادکردن دستگاه‌ها بدون تغییر رمز، از فرمان reset_devices استفاده کنید. رویدادهای مدیریت و صدور مجوز در پایگاه ثبت می‌شوند؛ رویدادهای بیش از ۱۸۰ روز و مجوزهای منقضی با سرویس نگهداری پاک می‌شوند.

برای به‌روزرسانی‌های سازگار نسخهٔ ۲، ابتدا بکاپ بگیرید؛ فایل‌های کد را جایگزین کنید و data، secrets، .env و volume پایگاه را حفظ کنید:

sudo docker compose stop api maintenance
sudo docker compose build --pull api
sudo docker compose run --rm api python manage.py migrate --noinput
sudo docker compose pull db proxy
sudo docker compose up -d

شمارهٔ اصلی PostgreSQL را بدون فرایند ارتقای پایگاه عوض نکنید. برای حذف آزمایشی کانتینرها از فرمان‌هایی که volume داده را پاک می‌کنند استفاده نکنید.

بازیابی روی سرور تازه

این مراحل برای مقصد خالی است. ابتدا بستهٔ نرم‌افزار را آماده و Docker را نصب کنید. از پوشهٔ server، آرشیو بکاپ مورد اعتماد را استخراج کنید تا data، secrets، .env و database.dump در جای خود باشند. کلید تازه نسازید. اگر دامنه تغییر کرده، فقط مقدار DOMAIN را اصلاح کنید:

sudo chown -R 10001:10001 data secrets
sudo chmod 700 data data/media secrets
sudo chmod 600 .env secrets/media_master_key
sudo chmod 755 init-db.sh
sudo docker compose build api
sudo docker compose up -d db
# Wait for the database health check to pass.
sudo docker compose exec -T db pg_restore -U postgres --role=poetvoice -d poetvoice --no-owner --exit-on-error < database.dump
sudo docker compose run --rm api python manage.py migrate --noinput
sudo docker compose up -d

پیش از استفاده، ورود مدیر، فعال‌سازی حساب و پخش یک شعر را بررسی کنید. بکاپ خام را در مسیر عمومی وب قرار ندهید. بازیابی روی پایگاه دارای داده نیاز به تصمیم و بکاپ جداگانه دارد؛ جدول‌های قدیمی و جدید را با هم مخلوط نکنید.

رفع مشکل

مشکلبررسی
اتصال گوشی برقرار نمی‌شودآدرس HTTPS بدون /admin، گواهی معتبر، DNS، سلامت سرور و به‌روز بودن WebView را بررسی کنید.
نسخهٔ برنامه پشتیبانی نمی‌شودAPK نسخهٔ ۲ یا جدیدتر لازم است. مسیر صوت مستقیم نسخهٔ قبلی حذف شده است.
اعتبار زمان درخواست رد می‌شودساعت و تاریخ گوشی و سرور را خودکار و دقیق تنظیم کنید.
پخش خطا می‌دهداینترنت، فعال‌بودن حساب و فایل MP3 سالم را بررسی کنید. دوباره وارد حساب شوید و QR را بخوانید. عملکرد واقعی گوشی باید آزموده شود.
فرم مدیر ذخیره نمی‌شودصفحه را تازه کنید و دوباره وارد شوید؛ توکن CSRF ممکن است منقضی شده باشد.
دستگاه سوم پذیرفته نمی‌شوداز دستگاه قبلی خارج شوید یا مدیر نشست‌ها را با reset_devices لغو کند.
سرور بعد از جابه‌جایی داده سالم نیستوجود کلید اصلی، تنظیمات درست PostgreSQL، مالکیت فایل‌ها و نتیجهٔ health را بررسی کنید. کلید را جایگزین نکنید.

چه چیزهایی بررسی شده‌اند؟

۱۱ آزمون سرور موفق و یک آزمون هم‌زمانی در این محیط اجرا نشده است. آزمون‌ها با Django و psycopg روی PostgreSQL 18.3 در PGlite اجرا شدند؛ PGlite تک‌اتصالی است و جای آزمون PostgreSQL بومی و بار واقعی را نمی‌گیرد. انتقال داده، حفاظت دسترسی، رمزگشایی قطعات و سازگاری رمزنگاری Python/Java بررسی شدند. APK ساخته و امضای آن تأیید شده است.

نصب Docker روی VPS واقعی، گواهی HTTPS واقعی و دوربین/پخش/Keystore روی گوشی واقعی در این محیط آزمایش نشده‌اند. پیش از توزیع به خریداران، مسیر کامل را روی گوشی‌های واقعی و با صوت خودتان آزمایش کنید. جزئیات در TEST-REPORT.md آمده است.