-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild_dmg.sh
More file actions
executable file
·181 lines (154 loc) · 5.84 KB
/
Copy pathbuild_dmg.sh
File metadata and controls
executable file
·181 lines (154 loc) · 5.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/bin/bash
set -e
echo "============================================"
echo " INFATON Control Center — DMG Builder"
echo "============================================"
APP_NAME="INFATON Control Center"
DMG_NAME="INFATON-Control-Center-4.0"
APP_PATH="/Applications/${APP_NAME}.app"
WORK_DIR="/tmp/dmg_build"
DMG_TEMP="${WORK_DIR}/${DMG_NAME}-temp.dmg"
DMG_FINAL="$HOME/Projects/automation/control-panel/dist/${DMG_NAME}.dmg"
# Check .app exists
if [ ! -d "$APP_PATH" ]; then
echo "[ERROR] ${APP_PATH} не найден!"
echo "Сначала запустите build_app.sh"
exit 1
fi
# Clean
rm -rf "$WORK_DIR"
mkdir -p "$WORK_DIR/dmg_content"
echo "[1/6] Копирование .app..."
cp -R "$APP_PATH" "$WORK_DIR/dmg_content/${APP_NAME}.app"
echo "[2/6] Создание ссылки на Applications..."
ln -s /Applications "$WORK_DIR/dmg_content/Applications"
# Copy docs
cp "$HOME/Projects/automation/control-panel/MANUAL.md" "$WORK_DIR/dmg_content/" 2>/dev/null || true
cp "$HOME/Projects/automation/control-panel/README-INSTALL.md" "$WORK_DIR/dmg_content/" 2>/dev/null || true
echo "[3/6] Создание фонового изображения..."
# Create background image with Python (no dependencies needed)
python3 << 'PYEOF'
import struct, zlib, os
W, H = 600, 400
def rgba(r, g, b, a=255):
return bytes([r, g, b, a])
def blend(bg, fg, alpha):
return int(bg * (1 - alpha) + fg * alpha)
def create_png_rgba(width, height, pixels):
"""Create RGBA PNG from raw pixel bytes"""
def chunk(chunk_type, data):
c = chunk_type + data
return struct.pack('>I', len(data)) + c + struct.pack('>I', zlib.crc32(c) & 0xffffffff)
raw = b''
for y in range(height):
raw += b'\x00' # filter byte
row_start = y * width * 4
raw += pixels[row_start:row_start + width * 4]
compressed = zlib.compress(raw, 9)
return (b'\x89PNG\r\n\x1a\n' +
chunk(b'IHDR', struct.pack('>IIBBBBB', width, height, 8, 6, 0, 0, 0)) +
chunk(b'IDAT', compressed) +
chunk(b'IEND', b''))
# Generate gradient background
pixels = bytearray(W * H * 4)
for y in range(H):
t = y / H
for x in range(W):
tx = x / W
# Dark blue gradient: top-left #1a1a2e → bottom-right #16213e
r = int(26 + (22 - 26) * t + (20 - 26) * tx * 0.3)
g = int(26 + (33 - 26) * t + (30 - 26) * tx * 0.3)
b = int(46 + (62 - 46) * t + (55 - 46) * tx * 0.3)
# Add subtle radial glow in center
cx, cy = 0.5, 0.35
dist = ((x/W - cx)**2 + (y/H - cy)**2) ** 0.5
glow = max(0, 1 - dist * 2.5) * 0.15
r = min(255, int(r + 233 * glow))
g = min(255, int(g + 69 * glow))
b = min(255, int(b + 96 * glow))
idx = (y * W + x) * 4
pixels[idx] = r
pixels[idx+1] = g
pixels[idx+2] = b
pixels[idx+3] = 255
png_data = create_png_rgba(W, H, bytes(pixels))
bg_dir = '/tmp/dmg_build/dmg_content/.background'
os.makedirs(bg_dir, exist_ok=True)
with open(bg_dir + '/background.png', 'wb') as f:
f.write(png_data)
print(f'Background: {W}x{H}, {len(png_data)} bytes')
PYEOF
echo "[4/6] Создание DMG..."
# Create temporary DMG
hdiutil create -srcfolder "$WORK_DIR/dmg_content" \
-volname "$APP_NAME" \
-fs HFS+ \
-fsargs "-c c=64,a=16,e=16" \
-format UDRW \
-size 20m \
"$DMG_TEMP" 2>/dev/null
echo "[5/6] Настройка внешнего вида..."
# Mount DMG
MOUNT_POINT=$(hdiutil attach -readwrite -noverify "$DMG_TEMP" 2>/dev/null | grep "/Volumes/" | sed 's/.*\/Volumes/\/Volumes/')
echo "Mounted at: $MOUNT_POINT"
if [ -n "$MOUNT_POINT" ]; then
# AppleScript to configure DMG window
osascript << ASEOF
tell application "Finder"
tell disk "$APP_NAME"
open
set current view of container window to icon view
set toolbar visible of container window to false
set statusbar visible of container window to false
set bounds of container window to {100, 100, 720, 520}
set theViewOptions to icon view options of container window
set arrangement of theViewOptions to not arranged
set icon size of theViewOptions to 96
try
set background picture of theViewOptions to file ".background:background.png"
end try
-- Position icons
set position of item "$APP_NAME.app" of container window to {160, 200}
set position of item "Applications" of container window to {450, 200}
try
set position of item "MANUAL.md" of container window to {300, 340}
end try
try
set position of item "README-INSTALL.md" of container window to {300, 340}
end try
close
open
update without registering applications
delay 2
close
end tell
end tell
ASEOF
# Hide background folder
SetFile -a V "$MOUNT_POINT/.background" 2>/dev/null || true
# Unmount
sync
hdiutil detach "$MOUNT_POINT" 2>/dev/null
fi
echo "[6/6] Сжатие финального DMG..."
mkdir -p "$(dirname "$DMG_FINAL")"
rm -f "$DMG_FINAL"
hdiutil convert "$DMG_TEMP" -format UDZO -imagekey zlib-level=9 -o "$DMG_FINAL" 2>/dev/null
# Cleanup
rm -rf "$WORK_DIR"
if [ -f "$DMG_FINAL" ]; then
SIZE=$(du -h "$DMG_FINAL" | cut -f1)
echo ""
echo "============================================"
echo " ✅ DMG создан!"
echo "============================================"
echo " Файл: $DMG_FINAL"
echo " Размер: $SIZE"
echo ""
echo " Установка: откройте DMG → перетащите"
echo " ${APP_NAME}.app в Applications"
echo "============================================"
else
echo "[ERROR] DMG не создан"
exit 1
fi