diff --git a/README.md b/README.md index e25f613..13f35a9 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,24 @@ Optional parameters for "zip" type package: Example for Kdenlive: ``` -/new-package.sh kdenlive -d "Kdenlive is a free and open-source video editing software." -n "Kdenlive" -g yes -u "https://download.kde.org/stable/kdenlive/22.12/windows/kdenlive-22.12.3.exe" -i "https://kdenlive.org/wp-content/uploads/2016/06/favico.png" -v 22.12.3 -t winbatch-nsis +new-package.sh \ + kdenlive \ + -d "Kdenlive is a free and open-source video editing software." \ + -n "Kdenlive" \ + -g yes \ + -u "https://download.kde.org/stable/kdenlive/22.12/windows/kdenlive-22.12.3.exe" \ + -i "https://kdenlive.org/wp-content/uploads/2016/06/favico.png" \ + -v 22.12.3 \ + -t winbatch-nsis ``` Then adjust the Uninstall path in uninstall.ins + + +Most basic example for weblinks package type: +``` +new-package.sh \ + link-collection \ + -t weblinks \ + -l "First link to Google;https://google.com;desktop" \ + -l "Another link but to Yahoo;https://yahoo.com;both" +``` \ No newline at end of file diff --git a/fetch-favicon.sh b/fetch-favicon.sh new file mode 100644 index 0000000..90db61a --- /dev/null +++ b/fetch-favicon.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +### +# Consumes a given image to convert it to ICO +# @param Path to the input file +### +function convertToIco { + imageWidth=$(identify -ping -format '%w ' "${1}" | awk -F' ' '{ print $NF }') + imageHeight=$(identify -ping -format '%h ' "${1}" | awk -F' ' '{ print $NF }') + + if [ ${imageWidth} -lt 64 ] || [ ${imageHeight} -lt 64 ]; then + echo "Warning: Favicon is only ${imageWidth}x${imageHeight}, it'll probably look pixely" + fi + + mimeType=$(file -bi "${1}") + if [ $? -eq 0 ] && ! grep -qE "^image/vnd.microsoft.icon" <<< "${mimeType}"; then + if convert "${1}" -resize "64x64" "$(dirname "${1}")/$(basename "${1}" ".${1##*.}").ico"; then + rm "${1}" + else + return 1 + fi + fi +} + +### +# Tries to download the favicon of a website +# @param URL of the website +# @param Filename of the downloaded ico file +### +function fetchFavicon { + domain=$(awk -F'/' '{ print $3 }' <<< "${1}") + protoAndDomain=$(awk -F'/' '{ print $1"//"$3 }' <<< "${1}") + + echo "Fetching favicon for ${protoAndDomain}" + + faviconUrl=$(curl -s -L "${1}" | grep -E '/dev/null) + if [ $? -eq 0 ] && [ "${faviconUrl}" != "" ]; then + if ! grep -E "https?://" <<< "${faviconUrl}"; then + faviconUrl="${protoAndDomain}${faviconUrl}" + fi + + mimeType=$(curl -Lso "${2}" -w "%{content_type}" "${faviconUrl}") + if [ $? -eq 0 ] && grep -E '^image/' <<< "${mimeType}"; then + echo "Success using link tag method" + convertToIco "${2}" + return 0 + fi + fi + + curlOut=($(curl -Lso "${2}" -w '%{http_code} %{content_type}' "${protoAndDomain}/favicon.ico")) + if [ $? -eq 0 ] && [ "${curlOut[0]}" = "200" ] && grep -qE '^image/' <<< "${curlOut[1]}"; then + echo "Success using /favicon.ico method" + convertToIco "${2}" + return 0 + fi + + curlOut=($(curl -Lso "${2}" -w '%{http_code} %{content_type}' "https://www.google.com/s2/favicons?domain=${domain}&sz=64")) + if [ $? -eq 0 ] && [ "${curlOut[0]}" = "200" ] && grep -qE '^image/' <<< "${curlOut[1]}"; then + echo "Success using Google Favicons API" + convertToIco "${2}" + return 0 + fi + + echo "Failed. You'll have to supply your own icon file at:" + echo " ${2}" +} diff --git a/new-package.sh b/new-package.sh index dcb7505..fb0b403 100644 --- a/new-package.sh +++ b/new-package.sh @@ -6,25 +6,33 @@ function usage { echo " $0 " echo "" echo "Optional parameters:" - echo " -d Adds a description to the package" - echo " -n Adds a product name instead of autogenerating one" - echo " -g yes Adds the Gruelag prefix to package ID and name" - echo " -u Downloads an installer file from the specified URL" - echo " -i Applies a logo to the package from the specified URL" - echo " -t Sets the type of package to create, see below" - echo " -v Sets the version of the program (not the package)" + echo " -d Adds a description to the package" + echo " -n Adds a product name instead of autogenerating one" + echo " -g yes Adds the Gruelag prefix to package ID and name, do not manually add Gruelag when using this!" + echo " -u Downloads an installer file from the specified URL" + echo " -i Applies a logo to the package from the specified URL" + echo " -t Sets the type of package to create, see below" + echo " -v Sets the version of the program (not the package)" echo "" echo "Package types:" - echo " winbatch Creates a blank WinBatch package" - echo " winbatch-inno Creates a blank INNO Installer WinBatch package" - echo " winbatch-nsis Creates a blank NSIS Installer WinBatch package" - echo " dosicon Creates a blank DosInAnIcon package" - echo " execps Creates a blank ExecWith Powershell package" - echo " zip Creates a blank ZIP based package" - echo " msi Creates a blank MSI installer package" + echo " winbatch Creates a blank WinBatch package" + echo " winbatch-inno Creates a blank INNO Installer WinBatch package" + echo " winbatch-nsis Creates a blank NSIS Installer WinBatch package" + echo " dosicon Creates a blank DosInAnIcon package" + echo " execps Creates a blank ExecWith Powershell package" + echo " zip Creates a blank ZIP based package" + echo " msi Creates a blank MSI installer package" + echo " weblinks Creates a weblink creator package" echo "" - echo "Optional parameters for ZIP type package:" - echo " -e Specifies the launcher executable inside the ZIP file" + echo "Parameters for 'zip' type package:" + echo " -e Optional, specifies the launcher executable inside the ZIP file" + echo "" + echo "Parameters for 'weblinks' type package:" + echo " -l ;;[] Can be used multiple times, specifies the URL and display name for one web link." + echo " is optional and can hold one of the following values:" + echo " 'desktop' to create only desktop links on the public user desktop" + echo " 'startmenu' to create links only in the public user start menu" + echo " 'both' to create links at both places, this is the default" } if [[ "$1" = "" ]]; then @@ -44,9 +52,10 @@ fi # Defaults programVersion="1.0" pkgType="default" +weblinks=() # Read command flags -while getopts ":d:g:n:t:e:u:i:v:" flag +while getopts ":d:g:n:t:e:u:i:v:l:" flag do case "${flag}" in d) productDescription="${OPTARG}";; @@ -57,27 +66,48 @@ do u) downloadUrl="${OPTARG}";; i) imageUrl="${OPTARG}";; v) programVersion="${OPTARG}";; + l) weblinks+=("${OPTARG}");; *) + echo "Unrecognized option '${flag}'" usage exit 0 ;; esac done -productId="${productIdPrefix}${productId}" +# Test if product ID was supplied empty +if [ "${productId}" = "" ]; then + echo "Product ID is empty, aborting!" + exit 1 +fi + +fullProductName="${productName}" -# Generate product name from ID if it's not set +# Generate product name from ID if it is not set already if [ "${productName}" = "" ]; then + # Replace dashes with spaces and uppercase first letter of every word productName=$(echo "${productId//-/ }" | sed -r 's/\<./\U&/g') fi -echo "-- Package data --" +# Prepend optional prefixes to product name and ID if they aren't already +if [ "${productIdPrefix}" != "" ] && \ + [ "${productId:0:${#productIdPrefix}}" != "${productIdPrefix}" ]; +then + productId="${productIdPrefix}${productId}" + fullProductName="${productNamePrefix}${productName}" +fi + + +# Dump some package info +echo "-- Package info --" echo "ID: ${productId}" -echo "Name: ${productName}" +echo "Name: ${fullProductName}" echo "Description: ${productDescription}" +echo "Type: ${pkgType}" echo "-- --" echo "" + echo "Creating package directory..." if [ -d "${productId}" ]; then echo "A folder with the package name already exists" @@ -88,13 +118,13 @@ elif ! mkdir "${productId}"; then fi pushd "${productId}" >/dev/null -echo "Creating control file..." -cat >control <<-EOF +echo "Creating control file..." +cat >control </dev/null fi -## START Some reusable code snippets as variables: + +# Some reusable code snippets as variables: read -r -d '' Sub_HandleExitCode <install.ins <<-EOF + [Initial] + Message=Installiere ${productName}... + DefVar \$PkgDir\$ + + [Actions] + ShowBitmap "%ScriptPath%\logo.png" "${productName}" + Sub_SetVars + Files_CopyIcons + Sub "%ScriptPath%\install-desktop.inc.ins" + Sub "%ScriptPath%\install-startmenu.inc.ins" + + [Sub_SetVars] + Set \$PkgDir\$ = "%ProgramFilesDir%\%installingProdName%" + + [Files_CopyIcons] + CheckTargetPath = "\$PkgDir\$" + Copy -s "%ScriptPath%\data\icons\" "\$PkgDir\$" + EOF + + cat >remove.ins <<-EOF + [Initial] + Message=Entferne ${productName}... + DefVar $PkgDir$ + + [Actions] + ShowBitmap "%ScriptPath%\logo.png" "${productName}" + Sub_SetVars + Files_DeleteIcons + Sub "%ScriptPath%\remove-desktop.inc.ins" + Sub "%ScriptPath%\remove-startmenu.inc.ins" + + [Sub_SetVars] + Set \$PkgDir\$ = "%ProgramFilesDir%\%installingProdName%" + + [Files_DeleteIcons] + Del -s -f "\$PkgDir\$" + EOF + + source ../fetch-favicon.sh + mkdir -p data/icons + + desktopLinkFolderList=$(mktemp) + startMenuLinkFolderList=$(mktemp) + + desktopRemoveFolderList=$(mktemp) + startMenuRemoveFolderList=$(mktemp) + + for (( i = 0; i < ${#weblinks[@]}; i++ )); do + link=${weblinks[${i}]} + linkName=$(echo "${link}" | awk -F';' '{ print $1 }') + linkInternalName=$(sed "s/[^a-zA-Z-]/_/g" <<< ${linkName}) + linkTarget=$(echo "${link}" | awk -F';' '{ print $2 }') + linkLocation=$(echo "${link}" | awk -F';' '{ print $3 }') + + # Desktop entries + if [ "${linkLocation}" = "desktop" ] || [ "${linkLocation}" = "both" ]; then + echo "LinkFolder_Desktop_${linkInternalName}" >> "install-desktop.inc.ins" + echo "LinkFolder_Remove_Desktop_${linkInternalName}" >> "remove-desktop.inc.ins" + + cat >>"${desktopLinkFolderList}" <>"${desktopRemoveFolderList}" <<-EOP + [LinkFolder_Remove_Desktop_${linkInternalName}] + Set_BaseFolder Common_DesktopDirectory + Set_SubFolder "" + Delete_Element "${linkName}" + + EOP + fi + + # Start menu entries + if [ "${linkLocation}" = "startmenu" ] || [ "${linkLocation}" = "both" ]; then + echo "LinkFolder_StartMenu_${linkInternalName}" >> "install-startmenu.inc.ins" + echo "LinkFolder_Remove_StartMenu_${linkInternalName}" >> "remove-startmenu.inc.ins" + + cat >>"${startMenuLinkFolderList}" <>"${startMenuRemoveFolderList}" <<-EOP + [LinkFolder_Remove_StartMenu_${linkInternalName}] + Set_BaseFolder Common_StartMenu + Set_SubFolder "" + Delete_Element "${linkName}" + + EOP + fi + + fetchFavicon "${linkTarget}" "data/icons/${linkInternalName}.ico" + done + + echo >> "install-desktop.inc.ins" + cat "${desktopLinkFolderList}" >> "install-desktop.inc.ins" + + echo >> "install-startmenu.inc.ins" + cat "${startMenuLinkFolderList}" >> "install-startmenu.inc.ins" + + echo >> "remove-desktop.inc.ins" + cat "${desktopRemoveFolderList}" >> "remove-desktop.inc.ins" + + echo >> "remove-startmenu.inc.ins" + cat "${startMenuRemoveFolderList}" >> "remove-startmenu.inc.ins" + + rm "${desktopLinkFolderList}" + rm "${startMenuLinkFolderList}" + rm "${desktopRemoveFolderList}" + rm "${startMenuRemoveFolderList}" + + ;; *) cat >install.ins <<-EOF