Skip to content

Commit c46c6e1

Browse files
committed
Packaging
Try to implement deb package for Debian/Ubuntu
1 parent 31f8d13 commit c46c6e1

20 files changed

Lines changed: 853 additions & 180 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,4 @@ use/*/
5050

5151
tests/users.sqlite3
5252
*.json
53+
debian/usr/bin/tgadmin

build-deb.sh

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
# ---------------------------------------------------------------------------
5+
# Configuration
6+
# ---------------------------------------------------------------------------
7+
VER_MAJOR="0"
8+
VER_MINOR=$(grep -oP '<MinorVersionNr Value="\K[^"]+' src/adminhelperd.lpi)
9+
VER_REV=$(grep -oP '<RevisionNr Value="\K[^"]+' src/adminhelperd.lpi)
10+
VER_BUILD=$(grep -oP '<BuildNr Value="\K[^"]+' src/adminhelperd.lpi)
11+
12+
export app_VER="${VER_MAJOR}.${VER_MINOR}.${VER_REV}"
13+
export app_VERdeb="${VER_BUILD}"
14+
15+
MAINTAINER_NAME="Renat Suleymanov"
16+
MAINTAINER_EMAIL="mail@Renat.Su"
17+
PACKAGE_NAME="tgadmin"
18+
19+
# ---------------------------------------------------------------------------
20+
# Paths
21+
# ---------------------------------------------------------------------------
22+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
23+
24+
# Build always happens in Linux fs to avoid NTFS chmod issues in WSL
25+
BUILD_DIR="/tmp/${PACKAGE_NAME}_build"
26+
27+
STAGING_DIR="${BUILD_DIR}/debian"
28+
DEB_NAME="${PACKAGE_NAME}_${app_VER}-${app_VERdeb}_amd64.deb"
29+
OUTPUT_DEB="${BUILD_DIR}/${DEB_NAME}"
30+
31+
# ---------------------------------------------------------------------------
32+
# Detect WSL
33+
# ---------------------------------------------------------------------------
34+
detect_wsl() {
35+
grep -qi microsoft /proc/version 2>/dev/null || \
36+
grep -qi wsl /proc/version 2>/dev/null
37+
}
38+
39+
# Where to copy the finished .deb.
40+
# Set via env: WINDOWS_OUTPUT_DIR="/mnt/c/Users/..." ./build-deb.sh
41+
if [ -n "${WINDOWS_OUTPUT_DIR:-}" ]; then
42+
COPY_TARGET="${WINDOWS_OUTPUT_DIR}"
43+
else
44+
COPY_TARGET="${SCRIPT_DIR}"
45+
fi
46+
47+
# ---------------------------------------------------------------------------
48+
# Dependencies' checking
49+
# ---------------------------------------------------------------------------
50+
check_deps() {
51+
local missing=()
52+
for cmd in dpkg-deb gzip du awk grep jq; do
53+
command -v "$cmd" &>/dev/null || missing+=("$cmd")
54+
done
55+
if [ ${#missing[@]} -gt 0 ]; then
56+
echo "ERROR: missing required tools: ${missing[*]}" >&2
57+
echo "Install with: sudo apt-get install dpkg-dev gzip jq" >&2
58+
exit 1
59+
fi
60+
}
61+
62+
# ---------------------------------------------------------------------------
63+
# Validate tgadmin.json before building
64+
# ---------------------------------------------------------------------------
65+
validate_config() {
66+
local config="${SCRIPT_DIR}/src/tgadmin.json"
67+
if [ ! -f "${config}" ]; then
68+
echo "ERROR: src/tgadmin.json not found" >&2
69+
exit 1
70+
fi
71+
if ! jq empty "${config}" 2>/dev/null; then
72+
echo "ERROR: src/tgadmin.json is not valid JSON" >&2
73+
exit 1
74+
fi
75+
}
76+
77+
# ---------------------------------------------------------------------------
78+
# Main
79+
# ---------------------------------------------------------------------------
80+
check_deps
81+
validate_config
82+
83+
echo "==> Building ${PACKAGE_NAME} v${app_VER}-${app_VERdeb}"
84+
echo "==> Build dir (Linux fs): ${BUILD_DIR}"
85+
86+
# Recreate build-dir in /tmp from scratch
87+
rm -rf "${BUILD_DIR}"
88+
mkdir -p "${BUILD_DIR}"
89+
90+
# Copy staging from sources in /tmp — here chmod works correctly
91+
cp -r "${SCRIPT_DIR}/debian" "${STAGING_DIR}"
92+
93+
# Include db_schema.sql — used by postinst to initialize the database
94+
mkdir -p "${STAGING_DIR}/usr/share/${PACKAGE_NAME}"
95+
cp "${SCRIPT_DIR}/src/db_schema.sql" "${STAGING_DIR}/usr/share/${PACKAGE_NAME}/db_schema.sql"
96+
97+
# Include tgadmin.json as default config
98+
# postinst will fill in DB credentials automatically
99+
mkdir -p "${STAGING_DIR}/etc/${PACKAGE_NAME}"
100+
cp "${SCRIPT_DIR}/src/tgadmin.json" "${STAGING_DIR}/etc/${PACKAGE_NAME}/tgadmin.json"
101+
102+
# Set permissions
103+
find "${STAGING_DIR}" -type d -exec chmod 0755 {} \;
104+
find "${STAGING_DIR}" -type f -exec chmod 0644 {} \;
105+
find "${STAGING_DIR}/usr/bin" -type f -exec chmod 0755 {} \;
106+
107+
# Maintainer scripts must be executable
108+
chmod 0755 "${STAGING_DIR}/DEBIAN/postinst"
109+
chmod 0755 "${STAGING_DIR}/DEBIAN/postrm"
110+
111+
# Config file should not be world-readable (contains credentials after install)
112+
chmod 0640 "${STAGING_DIR}/etc/${PACKAGE_NAME}/tgadmin.json"
113+
114+
# Version and size in control
115+
echo "Version: ${app_VER}.0-${app_VERdeb}" >> "${STAGING_DIR}/DEBIAN/control"
116+
SIZE_IN_KB="$(du -s "${STAGING_DIR}" | awk '{print $1}')"
117+
echo "Installed-Size: ${SIZE_IN_KB}" >> "${STAGING_DIR}/DEBIAN/control"
118+
119+
# Changelog
120+
CHANGELOG="${STAGING_DIR}/usr/share/doc/${PACKAGE_NAME}/changelog.Debian"
121+
DATE=$(date -R)
122+
{
123+
echo "${PACKAGE_NAME} (${app_VER}-${app_VERdeb}) unstable; urgency=medium"
124+
echo ""
125+
echo " * fixes"
126+
echo ""
127+
echo " -- ${MAINTAINER_NAME} <${MAINTAINER_EMAIL}> ${DATE}"
128+
} >> "${CHANGELOG}"
129+
gzip -9 -n "${CHANGELOG}"
130+
131+
# Package building
132+
dpkg-deb --root-owner-group --build "${STAGING_DIR}" "${OUTPUT_DEB}"
133+
134+
echo "==> Package built: ${OUTPUT_DEB}"
135+
136+
# Copy ready .deb to needed place
137+
mkdir -p "${COPY_TARGET}"
138+
cp "${OUTPUT_DEB}" "${COPY_TARGET}/"
139+
echo "==> Copied to: ${COPY_TARGET}/${DEB_NAME}"
140+
141+
echo "==> Done."

debian/DEBIAN/conffiles

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/etc/tgadmin/tgadmin.json

debian/DEBIAN/control

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Package: tgadmin
2+
Priority: optional
3+
Maintainer: Renat Suleymanov <mail@Renat.Su>
4+
Architecture: amd64
5+
Section: utils
6+
Depends: dash, libc6 (>= 2.2.5)
7+
Origin: https://github.com/al-Muhandis/AdminHelper
8+
Description: Telegram admin helper
9+
Telegram bot service for groups' moderation

debian/DEBIAN/postinst

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
PACKAGE_NAME="tgadmin"
5+
CONFIG_FILE="/etc/${PACKAGE_NAME}/tgadmin.json"
6+
SCHEMA_FILE="/usr/share/${PACKAGE_NAME}/db_schema.sql"
7+
8+
DB_NAME="tgadmin"
9+
DB_USER="tgadmin"
10+
11+
mysql_available() {
12+
command -v mysql &>/dev/null && mysqladmin ping --silent 2>/dev/null
13+
}
14+
15+
# Read current value from JSON (return empty string if null or missing)
16+
json_get() {
17+
jq -r "$1 // empty" "${CONFIG_FILE}" 2>/dev/null || true
18+
}
19+
20+
# Write values to JSON on the spot
21+
json_set() {
22+
local tmp
23+
tmp="$(mktemp)"
24+
jq "$1" "${CONFIG_FILE}" > "${tmp}" && mv "${tmp}" "${CONFIG_FILE}"
25+
}
26+
27+
case "$1" in
28+
configure)
29+
# ----------------------------------------------------------------
30+
# Check dependencies of postinst
31+
# ----------------------------------------------------------------
32+
for cmd in jq mysql mysqladmin openssl; do
33+
if ! command -v "$cmd" &>/dev/null; then
34+
echo "ERROR: required tool not found: ${cmd}" >&2
35+
echo "Install with: sudo apt-get install ${cmd}" >&2
36+
exit 1
37+
fi
38+
done
39+
40+
if [ ! -f "${CONFIG_FILE}" ]; then
41+
echo "ERROR: config file not found: ${CONFIG_FILE}" >&2
42+
echo " Place tgadmin.json into /etc/tgadmin/ before installing." >&2
43+
exit 1
44+
fi
45+
46+
# ----------------------------------------------------------------
47+
# Data base
48+
# ----------------------------------------------------------------
49+
if mysql_available; then
50+
# Take password from config if set (package update)
51+
EXISTING_PASS="$(json_get '.AdminHelperDB.Password')"
52+
53+
if [ -z "${EXISTING_PASS}" ]; then
54+
DB_PASS="$(openssl rand -base64 16 | tr -d '/+=' | head -c 20)"
55+
echo "==> Generated new database password."
56+
else
57+
DB_PASS="${EXISTING_PASS}"
58+
echo "==> Using existing database password from config."
59+
fi
60+
61+
echo "==> Configuring MySQL/MariaDB for ${DB_NAME}..."
62+
63+
mysql -u root <<SQL
64+
CREATE DATABASE IF NOT EXISTS \`${DB_NAME}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
65+
CREATE USER IF NOT EXISTS '${DB_USER}'@'localhost' IDENTIFIED BY '${DB_PASS}';
66+
GRANT ALL PRIVILEGES ON \`${DB_NAME}\`.* TO '${DB_USER}'@'localhost';
67+
FLUSH PRIVILEGES;
68+
SQL
69+
70+
# Rolling out the scheme (IF NOT EXISTS — safe when updating)
71+
mysql -u root "${DB_NAME}" < "${SCHEMA_FILE}"
72+
73+
# Write credentials to tgadmin.json
74+
json_set \
75+
--arg user "${DB_USER}" \
76+
--arg pass "${DB_PASS}" \
77+
--arg db "${DB_NAME}" \
78+
'.AdminHelperDB.User = $user | .AdminHelperDB.Password = $pass | .AdminHelperDB.Database = $db'
79+
80+
echo "==> Database configured. Credentials saved to ${CONFIG_FILE}"
81+
else
82+
echo "WARNING: MySQL/MariaDB not found or not running." >&2
83+
echo " Install it, then run: sudo dpkg-reconfigure ${PACKAGE_NAME}" >&2
84+
fi
85+
86+
# Configuration rights — only root and the tgadmin group
87+
chown root:${PACKAGE_NAME} "${CONFIG_FILE}" 2>/dev/null || chown root:root "${CONFIG_FILE}"
88+
chmod 0640 "${CONFIG_FILE}"
89+
;;
90+
esac
91+
92+
exit 0

debian/DEBIAN/postrm

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env bash
2+
set -euo pipefail
3+
4+
PACKAGE_NAME="tgadmin"
5+
CONFIG_FILE="/etc/${PACKAGE_NAME}/tgadmin.json"
6+
7+
DB_NAME="tgadmin"
8+
DB_USER="tgadmin"
9+
10+
mysql_available() {
11+
command -v mysql &>/dev/null && mysqladmin ping --silent 2>/dev/null
12+
}
13+
14+
case "$1" in
15+
purge)
16+
# purge = dpkg --purge, полное удаление с данными
17+
if mysql_available; then
18+
echo "==> Removing database and user for ${DB_NAME}..."
19+
mysql -u root <<SQL
20+
DROP DATABASE IF EXISTS \`${DB_NAME}\`;
21+
DROP USER IF EXISTS '${DB_USER}'@'localhost';
22+
FLUSH PRIVILEGES;
23+
SQL
24+
fi
25+
rm -f "${CONFIG_FILE}"
26+
rmdir --ignore-fail-on-non-empty "/etc/${PACKAGE_NAME}"
27+
;;
28+
remove)
29+
# remove = dpkg --remove, конфиг и данные остаются
30+
;;
31+
esac
32+
33+
exit 0
File renamed without changes.
Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2,38 +2,31 @@ msgid ""
22
msgstr "Content-Type: text/plain; charset=UTF-8"
33

44
#: actionadminhelper._sbnalrdyrlbck
5-
msgctxt "actionadminhelper._sbnalrdyrlbck"
65
msgid "This ban action has already been rolled back"
76
msgstr ""
87

98
#: actionadminhelper._sbnrlbck
10-
msgctxt "actionadminhelper._sbnrlbck"
119
msgid "The user's ban was rolled back: unbanning and rating returning "
1210
msgstr ""
1311

1412
#: actionadminhelper._scmplnntisfldbybt
15-
msgctxt "actionadminhelper._scmplnntisfldbybt"
1613
msgid "The complaint is filed by the bot itself"
1714
msgstr ""
1815

1916
#: actionadminhelper._scnfrmtnrlbckbn
20-
msgctxt "actionadminhelper._scnfrmtnrlbckbn"
2117
msgid "Do you think the ban was wrong? If the ban is rolled back, the complainant's rating will be downgraded and the inspected user who sent this message will be unbanned."
2218
msgstr ""
2319

2420
#: actionadminhelper._sdbgspminf
2521
#, object-pascal-format
26-
msgctxt "actionadminhelper._sdbgspminf"
2722
msgid "Ln spam probability: %n, Ln ham probability: %n. Spam Factor: %n"
2823
msgstr ""
2924

3025
#: actionadminhelper._shelptext
31-
msgctxt "actionadminhelper._shelptext"
3226
msgid "Help Text for TAdminHelper"
3327
msgstr ""
3428

3529
#: actionadminhelper._sinspctdmsgwschckdot
36-
msgctxt "actionadminhelper._sinspctdmsgwschckdot"
3730
msgid "The message has already been verified"
3831
msgstr ""
3932

@@ -42,54 +35,44 @@ msgid "It is identified as a spam based on emojies in the message"
4235
msgstr ""
4336

4437
#: actionadminhelper._sstarttext
45-
msgctxt "actionadminhelper._sstarttext"
4638
msgid "Start Text for TAdminHelper"
4739
msgstr ""
4840

4941
#: actionadminhelper._syrrghts
5042
#, object-pascal-format
51-
msgctxt "actionadminhelper._syrrghts"
5243
msgid "Status: %s"
5344
msgstr ""
5445

5546
#: actionadminhelper._syrrtng
5647
#, object-pascal-format
57-
msgctxt "actionadminhelper._syrrtng"
5848
msgid "Your rating is %d"
5949
msgstr ""
6050

6151
#: telegram_cmn._sbndusr
62-
msgctxt "telegram_cmn._sbndusr"
6352
msgid "Banned user"
6453
msgstr ""
6554

6655
#: telegram_cmn._scmplnnt
67-
msgctxt "telegram_cmn._scmplnnt"
6856
msgid "Complainant"
6957
msgstr ""
7058

7159
#: telegram_cmn._sinspctdmsg
72-
msgctxt "telegram_cmn._sinspctdmsg"
7360
msgid "Inspected message"
7461
msgstr ""
7562

7663
#: telegram_cmn._sinspctdmsghsdlt
77-
msgctxt "telegram_cmn._sinspctdmsghsdlt"
7864
msgid "The message was successfully deleted and the spammer was banned"
7965
msgstr ""
8066

8167
#: telegram_cmn._sinspctdmsgisntspm
82-
msgctxt "telegram_cmn._sinspctdmsgisntspm"
8368
msgid "The message is marked as NOT spam. Erroneous complaint"
8469
msgstr ""
8570

8671
#: telegram_cmn._sinspctdusr
87-
msgctxt "telegram_cmn._sinspctdusr"
8872
msgid "Inspected user"
8973
msgstr ""
9074

9175
#: telegram_cmn._sisernsbn
92-
msgctxt "telegram_cmn._sisernsbn"
9376
msgid "Is this erroneous ban?"
9477
msgstr ""
9578

@@ -99,18 +82,15 @@ msgid "Is this reaction spam? Emojies: %s"
9982
msgstr ""
10083

10184
#: telegram_cmn._smybitsntspm
102-
msgctxt "telegram_cmn._smybitsntspm"
10385
msgid "\"Probably it's not a spam\". More info..."
10486
msgstr ""
10587

10688
#: telegram_cmn._smybitsspm
107-
msgctxt "telegram_cmn._smybitsspm"
10889
msgid "\"Probably it's a spam\". More info..."
10990
msgstr ""
11091

11192
#: telegram_cmn._sprvntvlybnd
11293
#, object-pascal-format
113-
msgctxt "telegram_cmn._sprvntvlybnd"
11494
msgid "The user #`%0:d` [%1:s](tg://user?id=%0:d) was preventively banned"
11595
msgstr ""
11696

File renamed without changes.

0 commit comments

Comments
 (0)