Update installation script for metadata spelling
[geeqie.git] / geeqie-install-debian.sh
1 #!/bin/sh
2
3 ## @file
4 ## @brief Download, compile, and install Geeqie on Debian-based systems.
5 ##
6 ## If run from a folder that already contains the Geeqie sources, the source
7 ## code will be updated from the repository.
8 ## Dialogs allow the user to install additional features.
9 ##
10
11 version="2022-04-09"
12 description='
13 Geeqie is an image viewer.
14 This script will download, compile, and install Geeqie on Debian-based systems.
15 If run from a folder that already contains the Geeqie sources, the source
16 code will be updated from the repository.
17 Dialogs allow the user to install additional features.
18
19 Command line options are:
20 -v --version The version of this file
21 -h --help Output this text
22 -c --commit=ID Checkout and compile commit ID
23 -t --tag=TAG Checkout and compile TAG (e.g. v1.4 or v1.3)
24 -b --back=N Checkout commit -N (e.g. "-b 1" for last-but-one commit)
25 -l --list List required dependencies
26 -d --debug=yes Compile with debug output
27 '
28
29 # Essential for compiling
30 essential_array="git
31 build-essential
32 autoconf
33 libglib2.0-0
34 intltool
35 libtool
36 yelp-tools"
37
38 # Optional for both GTK2 and GTK3
39 optional_array="LCMS (for color management)
40 liblcms2-dev
41 exiv2 (for exif handling)
42 libgexiv2-dev
43 lua (for --remote commands)
44 liblua5.1-0-dev
45 libffmpegthumbnailer (for mpeg thumbnails)
46 libffmpegthumbnailer-dev
47 libtiff (for tiff support)
48 libtiff-dev
49 libjpeg (for jpeg support)
50 libjpeg-dev
51 librsvg2 (for viewing .svg images)
52 librsvg2-common
53 libwmf (for viewing .wmf images)
54 libwmf0.2-7-gtk
55 exiftran (for image rotation)
56 exiftran
57 imagemagick (for image rotation)
58 imagemagick
59 exiv2 command line (for jpeg export)
60 exiv2
61 jpgicc (for jpeg export color correction)
62 liblcms2-utils
63 pandoc (for generating README help file)
64 pandoc
65 gphoto2 (for tethered photography and camera download plugins)
66 gphoto2
67 libimage-exiftool-perl (for jpeg extraction plugin)
68 libimage-exiftool-perl
69 libheif (for HEIF support)
70 libheif-dev
71 libwebp (for WebP images)
72 libwebp-dev
73 libdjvulibre (for DjVu images)
74 libdjvulibre-dev
75 libopenjp2 (for JP2 images)
76 libopenjp2-7-dev
77 libraw (for CR3 images)
78 libraw-dev
79 libomp (required by libraw)
80 libomp-dev
81 libarchive (for compressed files e.g. zip, including timezone)
82 libarchive-dev"
83
84 # Optional for GTK3 only
85 optional_gtk3_array="libchamplain gtk (for GPS maps)
86 libchamplain-gtk-0.12-dev
87 libchamplain (for GPS maps)
88 libchamplain-0.12-dev
89 libpoppler (for pdf file preview)
90 libpoppler-glib-dev
91 libgspell (for spelling checks)
92 libgspell-1-dev"
93
94 ####################################################################
95 # Get System Info
96 # Derived from: https://github.com/coto/server-easy-install (GPL)
97 ####################################################################
98 lowercase()
99 {
100         printf '%b\n' "$1" | sed "y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/"
101 }
102
103 systemProfile()
104 {
105         OS="$(lowercase "$(uname)")"
106         KERNEL=$(uname -r)
107         MACH=$(uname -m)
108
109         if [ "${OS}" = "windowsnt" ]
110         then
111                 OS=windows
112         elif [ "${OS}" = "darwin" ]
113         then
114                 OS=mac
115         else
116                 OS=$(uname)
117                 if [ "${OS}" = "SunOS" ]
118                 then
119                         OS=Solaris
120                         ARCH=$(uname -p)
121                         OSSTR="${OS} ${REV}(${ARCH} $(uname -v))"
122                 elif [ "${OS}" = "AIX" ]
123                 then
124                         # shellcheck disable=SC2034
125                         OSSTR="${OS} $(oslevel) ($(oslevel -r))"
126                 elif [ "${OS}" = "Linux" ]
127                 then
128                         if [ -f /etc/redhat-release ]
129                         then
130                                 DistroBasedOn='RedHat'
131                                 DIST=$(sed s/\ release.*// /etc/redhat-release)
132                                 PSUEDONAME=$(sed s/.*\(// /etc/redhat-release | sed s/\)//)
133                                 REV=$(sed s/.*release\ // /etc/redhat-release | sed s/\ .*//)
134                         elif [ -f /etc/SuSE-release ]
135                         then
136                                 DistroBasedOn='SuSe'
137                                 PSUEDONAME=$(tr "\n" ' ' < /etc/SuSE-release | sed s/VERSION.*//)
138                                 REV=$(tr "\n" ' ' < /etc/SuSE-release | sed s/.*=\ //)
139                         elif [ -f /etc/mandrake-release ]
140                         then
141                                 DistroBasedOn='Mandrake'
142                                 PSUEDONAME=$(sed s/.*\(// /etc/mandrake-release | sed s/\)//)
143                                 REV=$(cat | sed s/.*release\ // /etc/mandrake-release | sed s/\ .*//)
144                         elif [ -f /etc/debian_version ]
145                         then
146                                 DistroBasedOn='Debian'
147                                 if [ -f /etc/lsb-release ]
148                                 then
149                                         DIST=$(grep '^DISTRIB_ID' /etc/lsb-release | awk -F= '{ print $2 }')
150                                         PSUEDONAME=$(grep '^DISTRIB_CODENAME' /etc/lsb-release | awk -F= '{ print $2 }')
151                                         REV=$(grep '^DISTRIB_RELEASE' /etc/lsb-release | awk -F= '{ print $2 }')
152                                 fi
153                         fi
154                         if [ -f /etc/UnitedLinux-release ]
155                         then
156                                 DIST="${DIST}[$(tr "\n" ' ' < /etc/UnitedLinux-release | sed s/VERSION.*//)]"
157                         fi
158                         OS=$(lowercase $OS)
159                         DistroBasedOn=$(lowercase $DistroBasedOn)
160                         readonly OS
161                         readonly DIST
162                         readonly DistroBasedOn
163                         readonly PSUEDONAME
164                         readonly REV
165                         readonly KERNEL
166                         readonly MACH
167                 fi
168         fi
169 }
170
171 install_essential()
172 {
173         i=0
174
175         for file in $essential_array
176         do
177                 if [ $((i % 2)) -ne 0 ]
178                 then
179                         if package_query "$file"
180                         then
181                                 package_install "$file"
182                         fi
183                 fi
184
185                 i=$((i + 1))
186         done
187
188         if [ "$1" = "GTK3" ]
189         then
190                 if package_query "libgtk-3-dev"
191                 then
192                         package_install libgtk-3-dev
193                 fi
194         else
195                 if package_query "libgtk2.0-dev"
196                 then
197                         package_install libgtk2.0-dev
198                 fi
199         fi
200 }
201
202 install_options()
203 {
204         if [ -n "$options" ]
205         then
206                 OLDIFS=$IFS
207                 IFS='|'
208                 set "$options"
209                 while [ $# -gt 0 ]
210                 do
211                         package_install "$1"
212                         shift
213                 done
214                 IFS=$OLDIFS
215         fi
216 }
217
218 uninstall()
219 {
220         current_dir="$(basename "$PWD")"
221         if [ "$current_dir" = "geeqie" ]
222         then
223
224                 sudo --askpass make uninstall
225
226                 if ! zenity --title="Uninstall Geeqie" --width=370 --text="WARNING.\nThis will delete folder:\n\n$PWD\n\nand all sub-folders!" --question --ok-label="Cancel" --cancel-label="OK" 2> /dev/null
227                 then
228                         cd ..
229                         sudo --askpass rm -rf geeqie
230                 fi
231         else
232                 zenity --title="Uninstall Geeqie" --width=370 --text="This is not a geeqie installation folder!\n\n$PWD" --warning 2> /dev/null
233         fi
234
235         exit_install
236 }
237
238 package_query()
239 {
240         if [ "$DistroBasedOn" = "debian" ]
241         then
242
243                 # shellcheck disable=SC2086
244                 res=$(dpkg-query --show --showformat='${Status}' "$1" 2>> $install_log)
245                 if [ "${res}" = "install ok installed" ]
246                 then
247                         status=1
248                 else
249                         status=0
250                 fi
251         fi
252         return $status
253 }
254
255 package_install()
256 {
257         if [ "$DistroBasedOn" = "debian" ]
258         then
259                 # shellcheck disable=SC2024
260                 sudo --askpass apt-get --assume-yes install "$@" >> "$install_log" 2>&1
261         fi
262 }
263
264 exit_install()
265 {
266         rm "$install_pass_script" > /dev/null 2>&1
267
268         if [ -p "$zen_pipe" ]
269         then
270                 printf '%b\n' "100" > "$zen_pipe"
271                 printf '%b\n' "#End" > "$zen_pipe"
272         fi
273
274         zenity --title="$title" --width=370 --text="Geeqie is not installed\nLog file: $install_log" --info 2> /dev/null
275
276         rm "$zen_pipe" > /dev/null 2>&1
277
278         exit 1
279 }
280
281 # Entry point
282
283 IFS='
284 '
285
286 # If uninstall has been run, maybe the current directory no longer exists
287 if [ ! -d "$PWD" ]
288 then
289         zenity --error --title="Install Geeqie and dependencies" --width=370 --text="Folder $PWD does not exist!" 2> /dev/null
290
291         exit
292 fi
293
294 # Check system type
295 systemProfile
296 if [ "$DistroBasedOn" != "debian" ]
297 then
298         zenity --error --title="Install Geeqie and dependencies" --width=370 --text="Unknown operating system:\n
299 Operating System: $OS
300 Distribution: $DIST
301 Psuedoname: $PSUEDONAME
302 Revision: $REV
303 DistroBasedOn: $DistroBasedOn
304 Kernel: $KERNEL
305 Machine: $MACH" 2> /dev/null
306
307         exit
308 fi
309
310 # Parse the command line
311 OPTS=$(getopt -o vhc:t:b:ld: --long version,help,commit:,tag:,back:,list,debug: -- "$@")
312 eval set -- "$OPTS"
313
314 while true
315 do
316         case "$1" in
317                 -v | --version)
318                         printf '%b\n' "$version"
319                         exit
320                         ;;
321                 -h | --help)
322                         printf '%b\n' "$description"
323                         exit
324                         ;;
325                 -c | --commit)
326                         COMMIT="$2"
327                         shift
328                         shift
329                         ;;
330                 -t | --tag)
331                         TAG="$2"
332                         shift
333                         shift
334                         ;;
335                 -b | --back)
336                         BACK="$2"
337                         shift
338                         shift
339                         ;;
340                 -l | --list)
341                         LIST="$2"
342                         shift
343                         shift
344                         ;;
345                 -d | --debug)
346                         DEBUG="$2"
347                         shift
348                         shift
349                         ;;
350                 *)
351                         break
352                         ;;
353         esac
354 done
355
356 if [ "$LIST" ]
357 then
358         printf '%b\n' "Essential libraries:"
359         for file in $essential_array
360         do
361                 printf '%b\n' "$file"
362         done
363
364         printf '\n'
365         printf '%b\n' "Optional libraries:"
366         for file in $optional_array
367         do
368                 printf '%b\n' "$file"
369         done
370
371         printf '\n'
372         printf '%b\n' "Optional for GTK3:"
373         for file in $optional_gtk3_array
374         do
375                 printf '%b\n' "$file"
376         done
377
378         exit
379 fi
380
381 # If a Geeqie folder already exists here, warn the user
382 if [ -d "geeqie" ]
383 then
384         zenity --info --title="Install Geeqie and dependencies" --width=370 --text="This script is for use on Ubuntu and other\nDebian-based installations.\nIt will download, compile, and install Geeqie source\ncode and its dependencies.\n\nA sub-folder named \"geeqie\" will be created in the\nfolder this script is run from, and the source code\nwill be downloaded to that sub-folder.\n\nA sub-folder of that name already exists.\nPlease try another folder." 2> /dev/null
385
386         exit
387 fi
388
389 # If it looks like a Geeqie download folder, assume an update
390 if [ -d ".git" ] && [ -d "src" ] && [ -f "geeqie.1" ]
391 then
392         mode="update"
393 else
394         # If it looks like something else is already installed here, warn the user
395         if [ -d ".git" ] || [ -d "src" ]
396         then
397                 zenity --info --title="Install Geeqie and dependencies" --width=370 --text="This script is for use on Ubuntu and other\nDebian-based installations.\nIt will download, compile, and install Geeqie source\ncode and its dependencies.\n\nIt looks like you are running this script from a folder which already has software installed.\n\nPlease try another folder." 2> /dev/null
398
399                 exit
400         else
401                 mode="install"
402         fi
403 fi
404
405 # Use GTK3 as default
406 gtk2_installed=FALSE
407 gtk3_installed=TRUE
408
409 if [ "$mode" = "install" ]
410 then
411         message="This script is for use on Ubuntu and other\nDebian-based installations.\nIt will download, compile, and install Geeqie source\ncode and its dependencies.\n\nA sub-folder named \"geeqie\" will be created in the\nfolder this script is run from, and the source code\nwill be downloaded to that sub-folder.\n\nIn this dialog you must select whether to compile\nfor GTK2 or GTK3.\nIf you want to use GPS maps or pdf preview,\nyou must choose GTK3.\nThe GTK2 version has a slightly different\nlook-and-feel compared to the GTK3 version,\nbut otherwise has the same features.\nYou may easily switch between the two after\ninstallation.\n\nIn subsequent dialogs you may choose which\noptional features to install."
412
413         title="Install Geeqie and dependencies"
414         install_option=TRUE
415 else
416         message="This script is for use on Ubuntu and other\nDebian-based installations.\nIt will update the Geeqie source code and its\ndependencies, and will compile and install Geeqie.\n\nYou may also switch the installed version from\nGTK2 to GTK3 and vice versa.\n\nIn this dialog you must select whether to compile\nfor GTK2 or GTK3.\nIf you want to use GPS maps or pdf preview,\nyou must choose GTK3.\nThe GTK2 version has a slightly different\nlook-and-feel compared to the GTK3 version,\nbut otherwise has the same features.\n\nIn subsequent dialogs you may choose which\noptional features to install."
417
418         title="Update Geeqie and re-install"
419         install_option=FALSE
420
421         # When updating, use previous installation as default
422         if [ -f config.log ]
423         then
424                 if grep gtk-2.0 config.log > /dev/null
425                 then
426                         gtk2_installed=TRUE
427                         gtk3_installed=FALSE
428                 else
429                         gtk2_installed=FALSE
430                         gtk3_installed=TRUE
431                 fi
432         fi
433 fi
434
435 # Ask whether to install GTK2 or GTK3 or uninstall
436
437 if ! gtk_version=$(zenity --title="$title" --width=370 --text="$message" --list --radiolist --column "" --column "" "$gtk3_installed" "GTK3 (required for GPS maps and pdf preview)" "$gtk2_installed" "GTK2" FALSE "Uninstall" --cancel-label="Cancel" --ok-label="OK" --hide-header 2> /dev/null)
438 then
439         exit
440 fi
441
442 # Environment variable SUDO_ASKPASS cannot be "zenity --password",
443 # so create a temporary script containing the command
444 install_pass_script=$(mktemp "${TMPDIR:-/tmp}/geeqie.XXXXXXXXXX")
445 printf '%b\n' "#!/bin/sh
446 if zenity --password --title=\"$title\" --width=370 2>/dev/null
447 then
448         exit 1
449 fi" > "$install_pass_script"
450 chmod +x "$install_pass_script"
451 export SUDO_ASKPASS=$install_pass_script
452
453 if [ "$gtk_version" = "Uninstall" ]
454 then
455         uninstall
456         exit
457 fi
458
459 # Put the install log in tmp, to avoid writing to PWD during a new install
460 rm install.log 2> /dev/null
461 install_log=$(mktemp "${TMPDIR:-/tmp}/geeqie.XXXXXXXXXX")
462
463 sleep 100 | zenity --title="$title" --text="Checking for installed files" --width=370 --progress --pulsate 2> /dev/null &
464 zen_pid=$!
465
466 # Get the standard options that are not yet installed
467 i=0
468 for file in $optional_array
469 do
470         if [ $((i % 2)) -eq 0 ]
471         then
472                 package_title="$file"
473         else
474                 if package_query "$file"
475                 then
476                         if [ -z "$option_string" ]
477                         then
478                                 option_string="${install_option:+${install_option}}\n${file}\n${file}"
479                         else
480                                 option_string="${option_string:+${option_string}}\n$install_option\n${package_title}\n${file}"
481                         fi
482                 fi
483         fi
484         i=$((i + 1))
485 done
486
487 # If GTK3 required, get the GTK3 options not yet installed
488 if [ -z "${gtk_version%%GTK3*}" ]
489 then
490         i=0
491         for file in $optional_gtk3_array
492         do
493                 if [ $((i % 2)) -eq 0 ]
494                 then
495                         package_title="$file"
496                 else
497                         if package_query "$file"
498                         then
499                                 if [ -z "$option_string" ]
500                                 then
501                                         option_string="${install_option:+${install_option}}\n${file}\n${file}"
502                                 else
503                                         option_string="${option_string:+${option_string}}\n$install_option\n${package_title}\n${file}"
504                                 fi
505                         fi
506                 fi
507                 i=$((i + 1))
508         done
509 fi
510
511 kill $zen_pid 2> /dev/null
512
513 # Ask the user which options to install
514 if [ -n "$option_string" ]
515 then
516         if ! options=$(printf '%b\n' "$option_string" | zenity --title="$title" --width=400 --height=500 --list --checklist --text 'Select which library files to install:' --column='Select' --column='Library files' --column='Library' --hide-column=3 --print-column=3 2> /dev/null)
517         then
518                 exit_install
519         fi
520 fi
521
522 # Start of Zenity progress section
523 zen_pipe=$(mktemp -u "${TMPDIR:-/tmp}/geeqie.XXXXXXXXXX")
524 mkfifo "$zen_pipe"
525 (tail -f "$zen_pipe" 2> /dev/null) | zenity --progress --title="$title" --width=370 --text="Installing options..." --auto-close --auto-kill --percentage=0 2> /dev/null &
526
527 printf '%b\n' "2" > "$zen_pipe"
528 printf '%b\n' "#Installing essential libraries..." > "$zen_pipe"
529
530 install_essential "$gtk_version"
531
532 printf '%b\n' "4" > "$zen_pipe"
533 printf '%b\n' "#Installing options..." > "$zen_pipe"
534
535 install_options
536
537 printf '%b\n' "6" > "$zen_pipe"
538 printf '%b\n' "#Installing extra loaders..." > "$zen_pipe"
539
540 printf '%b\n' "10" > "$zen_pipe"
541 printf '%b\n' "#Getting new sources from server..." > "$zen_pipe"
542
543 if [ "$mode" = "install" ]
544 then
545         if ! git clone git://geeqie.org/geeqie.git >> "$install_log" 2>&1
546         then
547                 git_error=$(tail -n5 "$install_log" 2>&1)
548                 zenity --title="$title" --width=370 --height=400 --error --text="Git error:\n\n$git_error" 2> /dev/null
549                 exit_install
550         fi
551 else
552         if ! git checkout master >> "$install_log" 2>&1
553         then
554                 git_error="$(tail -n25 "$install_log" 2>&1)"
555                 zenity --title="$title" --width=370 --height=400 --error --text="Git error:\n\n$git_error" 2> /dev/null
556                 exit_install
557         fi
558         if ! git pull >> "$install_log" 2>&1
559         then
560                 git_error=$(tail -n5 "$install_log" 2>&1)
561                 zenity --title="$title" --width=370 --height=400 --error --text="Git error:\n\n$git_error" 2> /dev/null
562                 exit_install
563         fi
564 fi
565
566 printf '%b\n' "20" > "$zen_pipe"
567 printf '%b\n' "#Cleaning installed version..." > "$zen_pipe"
568
569 if [ $mode = "install" ]
570 then
571         cd geeqie || exit 1
572 else
573         # shellcheck disable=SC2024
574         sudo --askpass make uninstall >> "$install_log" 2>&1
575         # shellcheck disable=SC2024
576         sudo --askpass make maintainer-clean >> "$install_log" 2>&1
577 fi
578
579 printf '%b\n' "30" > "$zen_pipe"
580 printf '%b\n' "#Checkout required version..." > "$zen_pipe"
581
582 if [ "$BACK" ]
583 then
584         if ! git checkout master~"$BACK" >> "$install_log" 2>&1
585         then
586                 git_error=$(tail -n5 "$install_log" 2>&1)
587                 zenity --title="$title" --width=370 --height=400 --error --text="Git error:\n\n$git_error" 2> /dev/null
588                 exit_install
589         fi
590 elif [ "$COMMIT" ]
591 then
592
593         if ! git checkout "$COMMIT" >> "$install_log" 2>&1
594         then
595                 git_error=$(tail -n5 "$install_log" 2>&1)
596                 zenity --title="$title" --width=370 --height=400 --error --text="Git error:\n\n$git_error" 2> /dev/null
597                 exit_install
598         fi
599 elif [ "$TAG" ]
600 then
601         if ! git checkout "$TAG" >> "$install_log" 2>&1
602         then
603                 git_error=$(tail -n5 "$install_log" 2>&1)
604                 zenity --title="$title" --width=370 --height=400 --error --text="Git error:\n\n$git_error" 2> /dev/null
605                 exit_install
606                 exit
607         fi
608 fi
609 if [ "$DEBUG" = "yes" ]
610 then
611         debug_opt=""
612 else
613         debug_opt="--disable-debug-log"
614 fi
615
616 printf '%b\n' "40" > "$zen_pipe"
617 printf '%b\n' "#Creating configuration files..." > "$zen_pipe"
618
619 if [ -z "${gtk_version%%GTK3*}" ]
620 then
621         ./autogen.sh "$debug_opt" >> "$install_log" 2>&1
622 else
623         ./autogen.sh "$debug_opt" --disable-gtk3 >> "$install_log" 2>&1
624 fi
625
626 printf '%b\n' "60" > "$zen_pipe"
627 printf '%b\n' "#Compiling..." > "$zen_pipe"
628
629 export CFLAGS=$CFLAGS" -Wno-deprecated-declarations"
630 export CXXFLAGS=$CXXFLAGS" -Wno-deprecated-declarations"
631
632 if ! make -j >> "$install_log" 2>&1
633 then
634         zenity --title="$title" --width=370 --height=400 --error --text="Compile error" 2> /dev/null
635         exit_install
636         exit
637 fi
638
639 printf '%b\n' "90 " > "$zen_pipe"
640 printf '%b\n' "#Installing Geeqie..." > "$zen_pipe"
641
642 # shellcheck disable=SC2024
643 sudo --askpass make install >> "$install_log" 2>&1
644
645 rm "$install_pass_script"
646 mv -f "$install_log" install.log
647
648 printf '%b\n' "100 " > "$zen_pipe"
649 rm "$zen_pipe"
650
651 (for i in $(seq 0 4 100)
652 do
653         printf '%b\n' "$i"
654         sleep 0.1
655 done) | zenity --progress --title="$title" --width=370 --text="Geeqie installation complete...\n" --auto-close --percentage=0 2> /dev/null
656
657 exit