diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..eafa1528 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +**/bin/ +**/obj/ +.git/ +.vs/ +.env +**/node_modules/ diff --git a/.env.example b/.env.example new file mode 100644 index 00000000..5230ab72 --- /dev/null +++ b/.env.example @@ -0,0 +1,13 @@ +# Copy to .env and fill in. DNS A records for both domains must point at this server. +SITE_DOMAIN=divan.example.com +API_DOMAIN=api.divan.example.com + +# SQL Server: 8+ chars with upper, lower, digit and symbol +MSSQL_SA_PASSWORD= +# JWT signing key: generate with `openssl rand -base64 32` +JWT_SECRET= +# First login with this email (any valid password) becomes the admin +ADMIN_EMAIL= + +# Public sign-up needs SMTP (SmptConfig__* env vars); keep off until configured +SIGNUP_ENABLED=False diff --git a/.gitignore b/.gitignore index 256a1615..8753b34e 100644 --- a/.gitignore +++ b/.gitignore @@ -261,3 +261,4 @@ __pycache__/ *.pyc /Museum/dist/js /Museum/src/dist +.env diff --git a/DIVAN.md b/DIVAN.md new file mode 100644 index 00000000..3198934f --- /dev/null +++ b/DIVAN.md @@ -0,0 +1,58 @@ +# دیوان · Divan site + +This is a fork of [GanjoorService](https://github.com/ganjoor/GanjoorService) (GPL-3.0), the software behind ganjoor.net, adapted to serve **classical Urdu poetry and prose** from [divan-data](https://github.com/anas-rashid/divan-data). + +## Changes from upstream + +- **Branding:** "گنجور" becomes "دیوان" throughout the site. Upstream is credited in the footer. +- **Urdu basics:** pages are `lang="ur"`. The home page, footer and century groups (Hijri centuries, e.g. "تیرہویں صدی ہجری") are in Urdu. Deeper pages, such as admin and account pages, are still Persian. +- **Fonts:** Noto Nastaliq Urdu by default, with a **نستعلیق / نسخ** switch (Noto Naskh Arabic) at the bottom left. The choice is remembered per browser. +- **Footer:** links to Ganjoor-only services (Hafez divination, music index, etc.) are removed. Links to the Wikisource source, the data and the code are added. +- **Linux/Docker:** `Dockerfile` + `docker-compose.yml` (SQL Server 2022, API, site, Caddy for HTTPS). The code itself is unchanged apart from the text above. + +## Deploy (Ubuntu/Debian x86-64, e.g. Vultr) + +```sh +# 1. Docker +curl -fsSL https://get.docker.com | sh + +# 2. Code + config +git clone https://github.com/anas-rashid/divan.git && cd divan +cp .env.example .env && nano .env # domains, passwords, admin email + +# 3. DNS: point SITE_DOMAIN and API_DOMAIN (A records) at the server, then: +docker compose up -d --build # first build takes a few minutes +docker compose logs -f api # wait for "Application started" +``` + +SQL Server needs about 2 GB of RAM. Use a plan with at least 4 GB in total. + +### Load the data + +1. Open `https://SITE_DOMAIN/login` and sign in with `ADMIN_EMAIL` and any password that meets the password rules. That first login creates the admin account. +2. On the import page that opens (or **Admin → مالی و سایت → درونریزی دادهٔ عمومی**), choose **Internet URL** and enter: + ``` + https://cdn.jsdelivr.net/gh/anas-rashid/divan-data@main/ + ``` +3. The import runs in the background (about 11k poems). Century groups are rebuilt automatically when it finishes. + +Re-running the import adds new poems and leaves existing ones untouched, so it can be repeated after divan-data's daily sync. + +### Update + +```sh +git pull && docker compose up -d --build +``` + +## Build locally (macOS/Linux) + +```sh +dotnet build RMuseum/RMuseum.csproj -p:EnableWindowsTargeting=true +dotnet build GanjooRazor/GanjooRazor.csproj -p:EnableWindowsTargeting=true +``` + +Running it needs SQL Server, so use the Docker setup above. SQL Server's image is x86-64 only. + +## License + +GPL-3.0, same as upstream (see `LICENSE`). Data: see [divan-data](https://github.com/anas-rashid/divan-data). diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..e6225961 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,18 @@ +# Divan: builds RMuseum (API) or GanjooRazor (site) for Linux. +# The projects target net10.0-windows7.0 (their RSecurityBackend dependency only ships for it), but they +# only use the plain .NET + ASP.NET Core runtimes, so the framework-dependent output runs on Linux. +# docker build --build-arg PROJECT=RMuseum . +# docker build --build-arg PROJECT=GanjooRazor . +FROM mcr.microsoft.com/dotnet/sdk:10.0 AS build +ARG PROJECT +WORKDIR /src +COPY . . +RUN dotnet publish "$PROJECT/$PROJECT.csproj" -c Release -o /app -p:EnableWindowsTargeting=true + +FROM mcr.microsoft.com/dotnet/aspnet:10.0 +ARG PROJECT +ENV APP_DLL=$PROJECT.dll ASPNETCORE_HTTP_PORTS=8080 +WORKDIR /app +COPY --from=build /app . +EXPOSE 8080 +ENTRYPOINT ["sh", "-c", "exec dotnet \"$APP_DLL\""] diff --git a/GanjooRazor/Areas/Admin/Pages/Banners.cshtml.cs b/GanjooRazor/Areas/Admin/Pages/Banners.cshtml.cs index 57c70e50..65a4cd25 100644 --- a/GanjooRazor/Areas/Admin/Pages/Banners.cshtml.cs +++ b/GanjooRazor/Areas/Admin/Pages/Banners.cshtml.cs @@ -54,7 +54,7 @@ namespace GanjooRazor.Areas.Admin.Pages } else { - LastMessage = "لطفاً از گنجور خارج و مجددا به آن وارد شوید."; + LastMessage = "لطفاً از دیوان خارج و مجددا به آن وارد شوید."; } } @@ -89,7 +89,7 @@ namespace GanjooRazor.Areas.Admin.Pages } else { - return new BadRequestObjectResult("لطفاً از گنجور خارج و مجددا به آن وارد شوید."); + return new BadRequestObjectResult("لطفاً از دیوان خارج و مجددا به آن وارد شوید."); } } @@ -113,7 +113,7 @@ namespace GanjooRazor.Areas.Admin.Pages } else { - return new BadRequestObjectResult("لطفاً از گنجور خارج و مجددا به آن وارد شوید."); + return new BadRequestObjectResult("لطفاً از دیوان خارج و مجددا به آن وارد شوید."); } } return new JsonResult(true); @@ -150,7 +150,7 @@ namespace GanjooRazor.Areas.Admin.Pages } else { - LastMessage = "لطفاً از گنجور خارج و مجددا به آن وارد شوید."; + LastMessage = "لطفاً از دیوان خارج و مجددا به آن وارد شوید."; } } diff --git a/GanjooRazor/Areas/Admin/Pages/CatTrans.cshtml.cs b/GanjooRazor/Areas/Admin/Pages/CatTrans.cshtml.cs index d5635920..de23fbce 100644 --- a/GanjooRazor/Areas/Admin/Pages/CatTrans.cshtml.cs +++ b/GanjooRazor/Areas/Admin/Pages/CatTrans.cshtml.cs @@ -69,7 +69,7 @@ namespace GanjooRazor.Areas.Admin.Pages } else { - LastMessage = "لطفاً از گنجور خارج و مجددا به آن وارد شوید."; + LastMessage = "لطفاً از دیوان خارج و مجددا به آن وارد شوید."; return false; } } @@ -107,7 +107,7 @@ namespace GanjooRazor.Areas.Admin.Pages } else { - LastMessage = "لطفاً از گنجور خارج و مجددا به آن وارد شوید."; + LastMessage = "لطفاً از دیوان خارج و مجددا به آن وارد شوید."; return Page(); } } @@ -134,7 +134,7 @@ namespace GanjooRazor.Areas.Admin.Pages } else { - LastMessage = "لطفاً از گنجور خارج و مجددا به آن وارد شوید."; + LastMessage = "لطفاً از دیوان خارج و مجددا به آن وارد شوید."; return Page(); } } @@ -159,7 +159,7 @@ namespace GanjooRazor.Areas.Admin.Pages } else { - return new BadRequestObjectResult("لطفاً از گنجور خارج و مجددا به آن وارد شوید."); + return new BadRequestObjectResult("لطفاً از دیوان خارج و مجددا به آن وارد شوید."); } } } diff --git a/GanjooRazor/Areas/Admin/Pages/CatUtils.cshtml.cs b/GanjooRazor/Areas/Admin/Pages/CatUtils.cshtml.cs index 3bac265f..d6e2e5c2 100644 --- a/GanjooRazor/Areas/Admin/Pages/CatUtils.cshtml.cs +++ b/GanjooRazor/Areas/Admin/Pages/CatUtils.cshtml.cs @@ -1,4 +1,4 @@ -using GanjooRazor.Pages; +using GanjooRazor.Pages; using GanjooRazor.Utils; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; @@ -527,7 +527,7 @@ namespace GanjooRazor.Areas.Admin.Pages UrlSlug = tag, ShortName = name, FullName = name, - SourceType = "همراهان گنجور" + SourceType = "همراهان دیوان" }; } diff --git a/GanjooRazor/Areas/Admin/Pages/Donations.cshtml.cs b/GanjooRazor/Areas/Admin/Pages/Donations.cshtml.cs index 0259faf7..4896b503 100644 --- a/GanjooRazor/Areas/Admin/Pages/Donations.cshtml.cs +++ b/GanjooRazor/Areas/Admin/Pages/Donations.cshtml.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using System.Net.Http; using System.Text; @@ -149,7 +149,7 @@ namespace GanjooRazor.Areas.Admin.Pages } else { - LastMessage = "لطفاً از گنجور خارج و مجددا به آن وارد شوید."; + LastMessage = "لطفاً از دیوان خارج و مجددا به آن وارد شوید."; } } diff --git a/GanjooRazor/Areas/Admin/Pages/EarlierVersion.cshtml.cs b/GanjooRazor/Areas/Admin/Pages/EarlierVersion.cshtml.cs index 5064c9e5..27828bfe 100644 --- a/GanjooRazor/Areas/Admin/Pages/EarlierVersion.cshtml.cs +++ b/GanjooRazor/Areas/Admin/Pages/EarlierVersion.cshtml.cs @@ -1,4 +1,4 @@ -using GanjooRazor.Utils; +using GanjooRazor.Utils; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using Newtonsoft.Json; @@ -45,7 +45,7 @@ namespace GanjooRazor.Areas.Admin.Pages } else { - LastMessage = "لطفاً از گنجور خارج و مجددا به آن وارد شوید."; + LastMessage = "لطفاً از دیوان خارج و مجددا به آن وارد شوید."; } } diff --git a/GanjooRazor/Areas/Admin/Pages/EditQuoted.cshtml b/GanjooRazor/Areas/Admin/Pages/EditQuoted.cshtml index 9bdb7b13..202e7ea0 100644 --- a/GanjooRazor/Areas/Admin/Pages/EditQuoted.cshtml +++ b/GanjooRazor/Areas/Admin/Pages/EditQuoted.cshtml @@ -288,7 +288,7 @@
|
- کاربر گرامی، متأسفیم که به اطلاع برسانیم که به دلیل نقض قوانین استفاده از گنجور و به طور مشخص +کاربر گرامی، متأسفیم که به اطلاع برسانیم که به دلیل نقض قوانین استفاده از دیوان و به طور مشخص |
|
- حساب کاربری شما به همراه حاشیهها، خوانشها و سایر اطلاعات خصوصیتان از گنجور حذف شده است. امیدواریم در آینده در صورت تمایل به استفاده از گنجور در چارچوبهای قابل پذیرش برای ما با حساب کاربری جدیدی پذیرای شما باشیم. با این ایمیل امکان نامنویسی مجدد نخواهید داشت. +حساب کاربری شما به همراه حاشیهها، خوانشها و سایر اطلاعات خصوصیتان از دیوان حذف شده است. امیدواریم در آینده در صورت تمایل به استفاده از دیوان در چارچوبهای قابل پذیرش برای ما با حساب کاربری جدیدی پذیرای شما باشیم. با این ایمیل امکان نامنویسی مجدد نخواهید داشت. |
git clone شده) در پایگاهدادهٔ همین نسخه وارد میکند —
- راهی سریعتر و سادهتر برای راهاندازی یک فورک یا نسخهٔ محلی کارآمد از گنجور، بهجای واردکردن
+ راهی سریعتر و سادهتر برای راهاندازی یک فورک یا نسخهٔ محلی کارآمد از دیوان، بهجای واردکردن
فایلهای اسکوئللایت بهصورت جداگانه برای هر سخنور.