-
-
Notifications
You must be signed in to change notification settings - Fork 41
Expand file tree
/
Copy pathquickstart.sh
More file actions
executable file
·736 lines (636 loc) · 21.9 KB
/
quickstart.sh
File metadata and controls
executable file
·736 lines (636 loc) · 21.9 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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
#!/usr/bin/env bash
set -euo pipefail
APT_UPDATED=0
REPO_OWNER="eylenburg"
REPO_NAME="linoffice"
TARGET_DIR="$HOME/.local/bin/linoffice"
TMPDIR=$(mktemp -d)
GITHUB_API_URL="https://api.github.com/repos/${REPO_OWNER}/${REPO_NAME}/releases"
LINOFFICE_SCRIPT="$TARGET_DIR/gui/linoffice.py"
APPDATA_DIR="$HOME/.local/share/linoffice"
INSTALLED_PM_PACKAGES=()
INSTALLED_FLATPAKS=()
INSTALLED_PIP_PACKAGES=()
FLATPAK_USER=0
PIP_VENV=0
# Virtual environment support
USE_VENV=0
VENV_PATH=""
# Immutable system support
USE_IMMUTABLE=0
ensure_qt_xcb_runtime_deps() {
# Qt >= 6.5 may require libxcb-cursor at runtime:
# "xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platform plugin."
try_install_any libxcb-cursor0 xcb-cursor0 xcb-util-cursor || true
try_install_any libxkbcommon-x11-0 libxkbcommon-x11 || true
try_install_any libxcb-xinerama0 || true
# Common Qt xcb plugin runtime deps on Debian/Ubuntu/Mint-like systems.
try_install_any libx11-xcb1 || true
try_install_any libxcb1 || true
try_install_any libxcb-icccm4 || true
try_install_any libxcb-image0 || true
try_install_any libxcb-keysyms1 || true
try_install_any libxcb-randr0 || true
try_install_any libxcb-render-util0 || true
try_install_any libxcb-shape0 || true
try_install_any libxcb-shm0 || true
try_install_any libxcb-sync1 || true
try_install_any libxcb-xfixes0 || true
try_install_any libxrender1 || true
try_install_any libxi6 || true
try_install_any libgl1 libgl1-mesa-glx || true
try_install_any libglu1-mesa || true
}
##################################################
# PART 1: INSTALL DEPENDENCIES
##################################################
# Detect package manager and distro
detect_package_manager() {
if [ -f /etc/os-release ]; then
. /etc/os-release
DISTRO_ID=$ID
DISTRO_LIKE=${ID_LIKE:-}
else
echo "Cannot determine OS version"
exit 1
fi
# Check for immutable systems
if command -v rpm-ostree >/dev/null 2>&1; then
echo "Detected Fedora Atomic or another immutable system using rpm-ostree"
check_immutable_dependencies "rpm-ostree"
return
elif command -v transactional-update >/dev/null 2>&1; then
echo "Detected openSUSE MicroOS or another immutable system using transactional-update"
check_immutable_dependencies "transactional-update"
return
fi
# Other known immutable distros
case "$DISTRO_ID" in
steamos|kde-linux)
echo "Immutable distribution without usable system package manager detected: $DISTRO_ID"
# Set flag to use pip-based installation and set dummy package manager
USE_IMMUTABLE=1
PKG_MGR="unknown"
return
;;
esac
# Reject other systems
case "$DISTRO_ID" in
nixos|guix|slackware|gentoo|alpine)
echo "Unsupported system type: $DISTRO_ID"
exit 1
;;
esac
for mgr in apt dnf yum zypper pacman xbps-install eopkg urpmi; do
if command -v "$mgr" >/dev/null 2>&1; then
PKG_MGR=$mgr
return
fi
done
echo "Unsupported package manager"
exit 1
}
# Check dependencies for immutable systems
check_immutable_dependencies() {
local immutable_tool="$1"
local missing_pkgs=()
local need_pip=false
local need_flatpak=false
echo "Checking required packages for immutable system..."
# Check podman (always required)
if ! command -v podman >/dev/null 2>&1; then
missing_pkgs+=("podman")
fi
# Check Python (always required)
if ! command -v python3 >/dev/null 2>&1 && ! command -v python >/dev/null 2>&1; then
missing_pkgs+=("python3")
fi
# Check if we need pip (only if podman-compose or PySide6 are not available)
if ! pkg_exists podman-compose || ! python3 -c "import PySide6" 2>/dev/null; then
need_pip=true
if ! command -v pip3 >/dev/null 2>&1 && ! command -v pip >/dev/null 2>&1; then
missing_pkgs+=("python3-pip")
fi
fi
# Check if we need flatpak (only if FreeRDP is not available)
if ! freerdp_version_ok; then
need_flatpak=true
if ! command -v flatpak >/dev/null 2>&1; then
missing_pkgs+=("flatpak")
fi
fi
if [ ${#missing_pkgs[@]} -gt 0 ]; then
echo "❌ Missing required packages: ${missing_pkgs[*]}"
echo ""
echo "Please install them using:"
if [ "$immutable_tool" = "rpm-ostree" ]; then
echo " sudo rpm-ostree install ${missing_pkgs[*]}"
echo " sudo systemctl reboot"
elif [ "$immutable_tool" = "transactional-update" ]; then
echo " sudo transactional-update pkg install ${missing_pkgs[*]}"
echo " sudo transactional-update reboot"
fi
echo ""
echo "After reboot, run this installer again."
exit 1
fi
echo "✅ All required packages are available"
if [ "$need_pip" = true ]; then
echo "Will use pip for Python dependencies"
fi
if [ "$need_flatpak" = true ]; then
echo "Will use flatpak for FreeRDP"
fi
if [ "$need_pip" = false ] && [ "$need_flatpak" = false ]; then
echo "All dependencies already available via system packages"
fi
# Set flag to use pip-based installation and set dummy package manager
USE_IMMUTABLE=1
PKG_MGR="unknown"
return 0
}
# Generic install function
install_pkg() {
local pkg="$1"
local rc=1
# Check if sudo is available
if ! check_sudo; then
show_manual_install "$pkg"
fi
case "$PKG_MGR" in
apt)
if [ "$APT_UPDATED" -eq 0 ]; then
sudo apt-get update
APT_UPDATED=1
fi
sudo apt-get install -y "$pkg"
rc=$?
;;
dnf|yum)
sudo "$PKG_MGR" install -y "$pkg"
rc=$?
;;
zypper)
sudo zypper --non-interactive install "$pkg"
rc=$?
;;
pacman)
sudo pacman -S --noconfirm --needed "$pkg"
rc=$?
;;
xbps-install)
sudo xbps-install -Sy "$pkg"
rc=$?
;;
eopkg)
sudo eopkg install -y "$pkg"
rc=$?
;;
urpmi)
sudo urpmi --auto "$pkg"
rc=$?
;;
*)
echo "Unknown package manager: $PKG_MGR"
return 1
;;
esac
if [ $rc -eq 0 ]; then
INSTALLED_PM_PACKAGES+=("$pkg")
fi
return $rc
}
# Try list of possible package names
try_install_any() {
for name in "$@"; do
if install_pkg "$name"; then
return 0
fi
done
return 1
}
# Command check
pkg_exists() {
command -v "$1" >/dev/null 2>&1
}
# Check if sudo is available
check_sudo() {
if ! command -v sudo >/dev/null 2>&1; then
return 1
fi
return 0
}
# Function to show manual installation instructions
show_manual_install() {
local packages=("$@")
echo -e "\033[1;31mIt seems that sudo is not available on your system. Please manually install these packages:\033[0m"
echo -e "\033[1;31m${packages[*]}\033[0m"
exit 1
}
ensure_pip() {
if ! pkg_exists pip3 && ! pkg_exists pip; then
try_install_any python3-pip python-pip python-pip3 || {
echo "Failed to install pip"
exit 1
}
fi
}
# Detect available pip command (prefer pip3)
get_pip_cmd() {
if command -v pip3 >/dev/null 2>&1; then
echo pip3
elif command -v pip >/dev/null 2>&1; then
echo pip
else
echo "" # none
fi
}
# Check if python-dotenv is installed in the current environment
is_python_dotenv_installed() {
local pip_cmd
pip_cmd=$(get_pip_cmd)
if [ -n "$pip_cmd" ] && "$pip_cmd" show python-dotenv >/dev/null 2>&1; then
return 0
fi
return 1
}
freerdp_version_ok() {
if command -v xfreerdp >/dev/null 2>&1; then
ver=$(xfreerdp --version | grep -oP '\d+\.\d+\.\d+' | head -n1)
major=$(echo "$ver" | cut -d. -f1)
[ "$major" -ge 3 ]
else
return 1
fi
}
# Flatpak fallback
install_freerdp_flatpak() {
if ! pkg_exists flatpak; then
try_install_any flatpak || { echo "Failed to install flatpak"; exit 1; }
fi
# make sure to specifically detect flathub user, not flathub system
if ! flatpak remote-list | grep -q 'flathub.*user'; then
flatpak remote-add --if-not-exists --user flathub https://dl.flathub.org/repo/flathub.flatpakrepo
fi
flatpak install -y --user flathub com.freerdp.FreeRDP
INSTALLED_FLATPAKS+=("com.freerdp.FreeRDP")
FLATPAK_USER=1
}
# Virtual environment setup function
use_venv() {
local python_cmd=""
local venv_dir="$TARGET_DIR/venv"
# Find Python command
if command -v python3 >/dev/null 2>&1; then
python_cmd="python3"
elif command -v python >/dev/null 2>&1; then
python_cmd="python"
else
echo "Python not found, cannot create venv"
return 1
fi
# Check if venv module is available
if ! "$python_cmd" -c "import venv" 2>/dev/null; then
echo "venv module not available, falling back to system Python"
return 1
fi
echo "Creating virtual environment..."
if "$python_cmd" -m venv --system-site-packages "$venv_dir"; then
VENV_PATH="$venv_dir"
USE_VENV=1
echo "Virtual environment created successfully"
return 0
else
echo "Failed to create virtual environment, falling back to system Python"
return 1
fi
}
# Main script for installing dependencies
dependencies_main() {
detect_package_manager
if [ "$USE_IMMUTABLE" -eq 1 ]; then
echo "Detected distro: $DISTRO_ID (immutable system)"
else
echo "Detected distro: $DISTRO_ID, package manager: $PKG_MGR"
fi
echo "Checking podman..."
if ! pkg_exists podman; then
try_install_any podman || { echo "Failed to install podman"; exit 1; }
fi
echo "Checking Python 3..."
if ! pkg_exists python3 && ! pkg_exists python; then
try_install_any python3 python || { echo "Failed to install Python 3"; exit 1; }
fi
echo "Checking FreeRDP (version >= 3)..."
if freerdp_version_ok; then
echo "FreeRDP is already version >= 3"
if [ "$USE_IMMUTABLE" -eq 1 ]; then
echo "FreeRDP already available via system package manager"
fi
else
if [ "$USE_IMMUTABLE" -eq 1 ]; then
echo "Installing FreeRDP via flatpak for immutable system..."
install_freerdp_flatpak
else
try_install_any freerdp3 freerdp3-x11 freerdp || true
if ! freerdp_version_ok; then
echo "Falling back to Flatpak for FreeRDP"
install_freerdp_flatpak
fi
fi
fi
# Check if podman-compose needs to be installed via pip
NEED_PODMAN_COMPOSE_PIP=false
if ! pkg_exists podman-compose; then
if [ "$USE_IMMUTABLE" -eq 1 ]; then
echo "podman-compose not available, will install via pip for immutable system"
NEED_PODMAN_COMPOSE_PIP=true
else
try_install_any podman-compose || true
if ! pkg_exists podman-compose; then
echo "podman-compose not available via package manager, will install via pip"
NEED_PODMAN_COMPOSE_PIP=true
fi
fi
else
if [ "$USE_IMMUTABLE" -eq 1 ]; then
echo "podman-compose already available via system package manager"
fi
fi
# Check if python-dotenv needs to be installed (dependency of podman-compose)
NEED_PYTHON_DOTENV_PIP=false
if ! python3 -c "import dotenv" 2>/dev/null; then
if [ "$USE_IMMUTABLE" -eq 1 ]; then
echo "python-dotenv not available, will install via pip for immutable system"
NEED_PYTHON_DOTENV_PIP=true
else
try_install_any python3-python-dotenv python-python-dotenv python3-dotenv python-dotenv || true
if ! python3 -c "import dotenv" 2>/dev/null; then
echo "python-dotenv not available via package manager, will install via pip"
NEED_PYTHON_DOTENV_PIP=true
fi
fi
else
if [ "$USE_IMMUTABLE" -eq 1 ]; then
echo "python-dotenv already available via system package manager"
fi
fi
# Check if PySide6 needs to be installed via pip
NEED_PYSIDE6_PIP=false
if ! python3 -c "import PySide6" 2>/dev/null; then
if [ "$USE_IMMUTABLE" -eq 1 ]; then
echo "PySide6 not available, will install via pip for immutable system"
NEED_PYSIDE6_PIP=true
else
try_install_any python3-pyside6 python-pyside6 python3-pyside6.qtcore python3-pyside6.qtwidgets python-pyside6.qtuitools || true
if ! python3 -c "import PySide6" 2>/dev/null; then
echo "PySide6 not available via package manager, will install via pip"
NEED_PYSIDE6_PIP=true
fi
fi
else
if [ "$USE_IMMUTABLE" -eq 1 ]; then
echo "PySide6 already available via system package manager"
fi
fi
# Install Python dependencies via pip if needed
if [ "$NEED_PODMAN_COMPOSE_PIP" = true ] || [ "$NEED_PYSIDE6_PIP" = true ] || [ "$NEED_PYTHON_DOTENV_PIP" = true ]; then
echo "Setting up Python environment for pip installations..."
if use_venv; then
echo "Using virtual environment for Python dependencies"
source "$VENV_PATH/bin/activate"
if [ "$NEED_PYTHON_DOTENV_PIP" = true ]; then
echo "Installing python-dotenv via pip in virtual environment"
"$VENV_PATH/bin/pip" install python-dotenv
INSTALLED_PIP_PACKAGES+=("python-dotenv")
PIP_VENV=1
fi
if [ "$NEED_PODMAN_COMPOSE_PIP" = true ]; then
echo "Installing podman-compose via pip in virtual environment"
"$VENV_PATH/bin/pip" install podman-compose
INSTALLED_PIP_PACKAGES+=("podman-compose")
PIP_VENV=1
# Check if python-dotenv was installed as a dependency
if ! is_python_dotenv_installed && [ "$NEED_PYTHON_DOTENV_PIP" != true ]; then
echo "Installing python-dotenv (dependency of podman-compose) via pip in virtual environment"
"$VENV_PATH/bin/pip" install python-dotenv
INSTALLED_PIP_PACKAGES+=("python-dotenv")
fi
fi
if [ "$NEED_PYSIDE6_PIP" = true ]; then
echo "Installing PySide6 via pip in virtual environment"
ensure_qt_xcb_runtime_deps
"$VENV_PATH/bin/pip" install PySide6
INSTALLED_PIP_PACKAGES+=("PySide6")
PIP_VENV=1
fi
deactivate
else
echo "Using system Python"
if [ "$NEED_PYTHON_DOTENV_PIP" = true ]; then
echo "Installing python-dotenv via pip with --break-system-packages"
ensure_pip
pip3 install --user --break-system-packages python-dotenv || pip install --user --break-system-packages python-dotenv
INSTALLED_PIP_PACKAGES+=("python-dotenv")
fi
if [ "$NEED_PODMAN_COMPOSE_PIP" = true ]; then
echo "Installing podman-compose via pip with --break-system-packages"
ensure_pip
pip3 install --user --break-system-packages podman-compose || pip install --user --break-system-packages podman-compose
INSTALLED_PIP_PACKAGES+=("podman-compose")
export PATH="$HOME/.local/bin:$PATH"
# Check if python-dotenv was installed as a dependency
if ! is_python_dotenv_installed && [ "$NEED_PYTHON_DOTENV_PIP" != true ]; then
echo "Installing python-dotenv (dependency of podman-compose) via pip"
pip3 install --user --break-system-packages python-dotenv || pip install --user --break-system-packages python-dotenv
INSTALLED_PIP_PACKAGES+=("python-dotenv")
fi
fi
if [ "$NEED_PYSIDE6_PIP" = true ]; then
echo "Installing PySide6 via pip with --break-system-packages"
ensure_pip
ensure_qt_xcb_runtime_deps
pip3 install --user --break-system-packages PySide6 || pip install --user --break-system-packages PySide6
INSTALLED_PIP_PACKAGES+=("PySide6")
# Verify PySide6 installation
if ! python3 -c "import PySide6" 2>/dev/null; then
echo "Failed to install PySide6"
exit 1
fi
fi
fi
else
if [ "$USE_IMMUTABLE" -eq 1 ]; then
echo "All Python dependencies already available via system package manager"
fi
fi
echo "✅ All dependencies installed successfully!"
# Write installed dependencies summary
mkdir -p "$APPDATA_DIR"
SUMMARY_FILE="$APPDATA_DIR/installed_dependencies"
PM_KEY="$PKG_MGR"
pm_list="${INSTALLED_PM_PACKAGES[*]:-}"
flatpak_list="${INSTALLED_FLATPAKS[*]:-}"
pip_list="${INSTALLED_PIP_PACKAGES[*]:-}"
# Merge with existing summary if present
existing_pm_key=""
existing_pm_vals=""
existing_flatpak_vals=""
existing_pip_vals=""
existing_flatpak_user=0
existing_pip_venv=0
if [ -f "$SUMMARY_FILE" ]; then
existing_pm_key=$(grep -E '^(apt|dnf|yum|zypper|pacman|xbps-install|eopkg|urpmi)=' "$SUMMARY_FILE" | head -n1 | cut -d= -f1 || true)
if [ -n "${existing_pm_key}" ]; then
existing_pm_vals=$(grep -E "^${existing_pm_key}=" "$SUMMARY_FILE" | sed -E 's/^[^=]+=//; s/^"//; s/"$//' || true)
fi
existing_flatpak_vals=$(grep -E '^flatpak=' "$SUMMARY_FILE" | sed -E 's/^flatpak=//; s/^"//; s/"$//' || true)
existing_pip_vals=$(grep -E '^pip=' "$SUMMARY_FILE" | sed -E 's/^pip=//; s/^"//; s/"$//' || true)
existing_flatpak_user=$(grep -E '^flatpak_user=' "$SUMMARY_FILE" | tail -n1 | cut -d= -f2 || echo 0)
existing_pip_venv=$(grep -E '^pip_venv=' "$SUMMARY_FILE" | tail -n1 | cut -d= -f2 || echo 0)
fi
# Determine the key to use for package-manager line
pm_key_to_write="${existing_pm_key:-$PM_KEY}"
# Build unique merged lists
combined_pm=""
combined_flatpak=""
combined_pip=""
declare -A __seen_pm __seen_flatpak __seen_pip
for item in $existing_pm_vals $pm_list; do
[ -n "$item" ] || continue
if [ -z "${__seen_pm[$item]+x}" ]; then
combined_pm+="${combined_pm:+ }$item"
__seen_pm[$item]=1
fi
done
for item in $existing_flatpak_vals $flatpak_list; do
[ -n "$item" ] || continue
if [ -z "${__seen_flatpak[$item]+x}" ]; then
combined_flatpak+="${combined_flatpak:+ }$item"
__seen_flatpak[$item]=1
fi
done
for item in $existing_pip_vals $pip_list; do
[ -n "$item" ] || continue
if [ -z "${__seen_pip[$item]+x}" ]; then
combined_pip+="${combined_pip:+ }$item"
__seen_pip[$item]=1
fi
done
# Flags accumulate across runs (logical OR)
final_flatpak_user=0
if [ "${existing_flatpak_user}" = "1" ] || [ "${FLATPAK_USER}" = "1" ]; then
final_flatpak_user=1
fi
final_pip_venv=0
if [ "${existing_pip_venv}" = "1" ] || [ "${PIP_VENV}" = "1" ]; then
final_pip_venv=1
fi
{
echo "Dependencies installed by quickstart.sh:"
echo "${pm_key_to_write}=\"${combined_pm}\""
echo "flatpak=\"${combined_flatpak}\""
echo "pip=\"${combined_pip}\""
echo "flatpak_user=${final_flatpak_user}"
echo "pip_venv=${final_pip_venv}"
} > "$SUMMARY_FILE"
}
##################################################
# PART 2: DOWNLOAD LATEST LINOFFICE
##################################################
download_latest() {
echo "Fetching latest LinOffice version from GitHub..."
LATEST_VERSION=$(curl -sSL "$GITHUB_API_URL" | \
grep -E '"tag_name":\s*"v[0-9]+\.[0-9]+\.[0-9]+"' | \
grep -v '"prerelease": true' | \
grep -v '"draft": true' | \
head -n1 | \
sed -E 's/.*"v([0-9]+\.[0-9]+\.[0-9]+)".*/\1/')
if [[ -z "$LATEST_VERSION" ]]; then
echo "Error: Could not determine latest version."
exit 1
fi
ZIP_URL="https://github.com/${REPO_OWNER}/${REPO_NAME}/archive/refs/tags/v${LATEST_VERSION}.zip"
ZIP_FILE="$TMPDIR/linoffice.zip"
echo "Downloading Linoffice v${LATEST_VERSION} from:"
echo "$ZIP_URL"
# Modified: Add -L to follow redirects during status check
HTTP_STATUS=$(curl -s -L -o /dev/null -w "%{http_code}" "$ZIP_URL")
if [[ "$HTTP_STATUS" != "200" ]]; then
echo "Error: File not found at $ZIP_URL (HTTP $HTTP_STATUS)"
exit 1
fi
curl -L -o "$ZIP_FILE" "$ZIP_URL"
# Check it’s really a zip
if ! file "$ZIP_FILE" | grep -q "Zip archive data"; then
echo "Error: Downloaded file is not a valid zip archive."
file "$ZIP_FILE"
exit 1
fi
echo "Unzipping..."
unzip -q "$ZIP_FILE" -d "$TMPDIR"
# Expected folder name: linoffice-${LATEST_VERSION}
EXTRACTED_DIR="$TMPDIR/linoffice-${LATEST_VERSION}"
if [[ ! -d "$EXTRACTED_DIR" ]]; then
echo "Error: Expected folder 'linoffice-${LATEST_VERSION}' not found in zip."
exit 1
fi
# Determine source directory to install (prefer src/ if present)
SOURCE_DIR="$EXTRACTED_DIR"
if [[ -d "$EXTRACTED_DIR/src" ]]; then
echo "Detected 'src' directory inside archive; using its contents for installation."
SOURCE_DIR="$EXTRACTED_DIR/src"
fi
echo "Installing to $TARGET_DIR..."
# Check if TARGET_DIR exists and contains linoffice.sh
if [[ -d "$TARGET_DIR" && -f "$TARGET_DIR/linoffice.sh" ]]; then
echo "Existing installation found. Updating files..."
cp -a "$SOURCE_DIR"/. "$TARGET_DIR"/
else
# If TARGET_DIR doesn't exist or doesn't contain linoffice.sh, replace it with contents of SOURCE_DIR
rm -rf "$TARGET_DIR"
mkdir -p "$TARGET_DIR"
cp -a "$SOURCE_DIR"/. "$TARGET_DIR"/
fi
# Make everything executable
find "$TARGET_DIR" -type f \( -name "*.py" -o -name "*.sh" \) -exec chmod +x {} \;
rm -rf "$TMPDIR"
echo "✅ Linoffice v${LATEST_VERSION} installed at $TARGET_DIR"
}
##################################################
# PART 3: Run LinOffice
##################################################
start_linoffice() {
# Run the linoffice installer
echo "Starting Linoffice..."
# Check for virtual environment first, then fall back to system Python
if [[ "$USE_VENV" == "1" && -f "$VENV_PATH/bin/python3" ]]; then
PYTHON_CMD="$VENV_PATH/bin/python3"
elif command -v python3 >/dev/null 2>&1; then
PYTHON_CMD="python3"
elif command -v python >/dev/null 2>&1; then
PYTHON_CMD="python"
else
echo "Error: Python not found. Please install Python."
exit 1
fi
# Check if the linoffice.py script exists
if [[ ! -f "$LINOFFICE_SCRIPT" ]]; then
echo "Error: $LINOFFICE_SCRIPT not found. Please check the installation."
exit 1
fi
echo "Running $LINOFFICE_SCRIPT with $PYTHON_CMD..."
nohup "$PYTHON_CMD" "$LINOFFICE_SCRIPT" > /dev/null 2>&1 &
}
##################################################
# Main logic
##################################################
read -p "Welcome to the LinOffice installer. We will check and install dependencies, download the latest LinOffice release, and then run the main setup, which will install a Windows container with Microsoft Office. Are you sure you want to continue? (y/n): " confirmation
if [[ "$confirmation" == "y" || "$confirmation" == "Y" ]]; then
dependencies_main "$@"
download_latest
start_linoffice
else
echo "Cancelled."
exit 1
fi