Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updater.sh for t-bird #1

Open
atomGit opened this issue May 27, 2019 · 1 comment

Comments

@atomGit
Copy link

commented May 27, 2019

dummy here ... i don't know how to do a pull request

i stole updater.sh from the 'ghacks' repo and made some changes so it can work for either FF or TB

this ain't my expertise, so someone would have to check it - also search for [fix]

#!/usr/bin/env bash

# !!! search for [fix] !!!

## ghacks-user.js updater for macOS and Linux

## version: 1.0a
## based on 'ghacks' updater.sh v2.5 for Firefox
## Original author: Pat Johnson (@overdodactyl)
## Additional contributors: @earthlng, @ema-pe, @claustromaniac
## Adapted for Thunderbird by @atomGit

## DON'T GO HIGHER THAN VERSION x.9 !! ( because of ASCII comparison in update_updater() )

readonly CURRDIR=$(pwd)

sfp=$(readlink -f "${BASH_SOURCE[0]}" 2>/dev/null || greadlink -f "${BASH_SOURCE[0]}" 2>/dev/null)
if [ -z "$sfp" ]; then sfp=${BASH_SOURCE[0]}; fi
readonly SCRIPT_DIR=$(dirname "${sfp}")

#########################
#    Base variables     #
#########################

# Uncomment the group of variables below to update user.js for Firefox
#APPNAME='Firefox'
#MAINTAINER='@Thorin-Oakenpants and @earthlng'
#USERJS='https://raw.githubusercontent.com/ghacksuserjs/ghacks-user.js/master/user.js'
#UPDATERJS='https://raw.githubusercontent.com/ghacksuserjs/ghacks-user.js/master/updater.sh'
#DOCS='https://github.com/ghacksuserjs/ghacks-user.js/wiki'

# Uncomment the group of variables below to update user.js for Thunderbird
APPNAME='Thunderbird'
MAINTAINER='???'
USERJS='https://raw.githubusercontent.com/dngray/ghacks-thunderbird-user.js/master/user.js'
UPDATERJS='https://raw.githubusercontent.com/dngray/ghacks-thunderbird-user.js/master/updater.js'
DOCS='https://github.com/dngray/ghacks-thunderbird-user.js/wiki'

# Stop editing here

# Colors used for printing
RED='\033[0;31m'
#BLUE='\033[0;34m'
#BBLUE='\033[1;34m'
GREEN='\033[0;32m'
ORANGE='\033[0;33m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color

# Argument defaults
UPDATE='check'
CONFIRM='yes'
OVERRIDE='user-overrides.js'
BACKUP='multiple'
COMPARE=true
SKIPOVERRIDE=false
VIEW=false
PROFILE_PATH=false
ESR=false

# Download method priority: curl -> wget
DOWNLOAD_METHOD=''
if [[ $(command -v 'curl') ]]; then
  DOWNLOAD_METHOD='curl'
elif [[ $(command -v 'wget') ]]; then
  DOWNLOAD_METHOD='wget'
else
  echo -e "${RED}This script requires curl or wget.\nProcess aborted${NC}"
  exit 0
fi

show_banner () {
  echo -e "${GREEN}\n"
  echo '############################################################################'
  echo '####'
  echo "####   ghacks user.js for ${APPNAME}"
  echo "####   Hardening the Privacy and Security Settings of ${APPNAME}"
  echo "####   Maintained by ${MAINTAINER}"
  echo '####   Updater for macOS and Linux by @overdodactyl'
  echo '####   Documentation for this script is available here:'
  echo "####   ${DOCS}"
  echo '####'
  echo '############################################################################'
  echo -e "${NC}\n"
}

#########################
#      Arguments        #
#########################

usage() {
  echo -e "${GREEN}\nUsage: $0 [-h] [-p PROFILE] [-u] [-d] [-s] [-n] [-b] [-c] [-v] [-r] [-e] [-o OVERRIDE]\n${NC}" 1>&2  # Echo usage string to standard error
  echo 'Optional Arguments:'
  echo -e "\t-h,\t\t Show this help message and exit."
  echo -e "\t-p PROFILE,\t Path to your ${APPNAME} profile (if different than the dir of this script)"
  echo -e "\t\t\t IMPORTANT: if the path include spaces, wrap the entire argument in quotes."
  echo -e "\t-l, \t\t Choose your ${APPNAME} profile from a list"
  echo -e "\t-u,\t\t Update updater.sh and execute silently.  Do not seek confirmation."
  echo -e "\t-d,\t\t Do not look for updates to updater.sh."
  echo -e "\t-s,\t\t Silently update user.js.  Do not seek confirmation."
  echo -e "\t-b,\t\t Only keep one backup of each file."
  echo -e "\t-c,\t\t Create a diff file comparing old and new user.js within userjs_diffs. "
  echo -e "\t-o OVERRIDE,\t Filename or path to overrides file (if different than user-overrides.js)."
  echo -e "\t\t\t If used with -p, paths should be relative to PROFILE or absolute paths"
  echo -e "\t\t\t If given a directory, all files inside will be appended recursively."
  echo -e "\t\t\t You can pass multiple files or directories by passing a comma separated list."
  echo -e "\t\t\t\t Note: If a directory is given, only files inside ending in the extension .js are appended"
  echo -e "\t\t\t\t IMPORTANT: do not add spaces between files/paths.  Ex: -o file1.js,file2.js,dir1"
  echo -e "\t\t\t\t IMPORTANT: if any files/paths include spaces, wrap the entire argument in quotes."
  echo -e "\t\t\t\t\t Ex: -o \"override folder\" "
  echo -e "\t-n,\t\t Do not append any overrides, even if user-overrides.js exists."
  echo -e "\t-v,\t\t Open the resulting user.js file."
  echo -e "\t-r,\t\t Only download user.js to a temporary file and open it."
  echo -e "\t-e,\t\t Activate ESR related preferences."
  echo -e
  echo 'Deprecated Arguments (they still work for now):'
  echo -e "\t-donotupdate,\t Use instead -d"
  echo -e "\t-update,\t Use instead -u"
  echo -e
  exit 1
}

legacy_argument () {
  echo -e "${ORANGE}\nWarning: command line arguments have changed."
  echo -e "$1 has been deprecated and may not work in the future.\n"
  echo -e "Please view the new options using the -h argument.${NC}"
}

#########################
#     File Handling     #
#########################

# Download files
download_file () {
  declare -r url=$1
  declare -r tf=$(mktemp)
  local dlcmd=''

  if [ $DOWNLOAD_METHOD = 'curl' ]; then
    dlcmd="curl -o $tf"
  else
    dlcmd="wget -O $tf"
  fi

  $dlcmd "${url}" &>/dev/null && echo "$tf" || echo '' # return the temp-filename (or empty string on error)
}

open_file () { #expects one argument: file_path
  if [ "$(uname)" == 'Darwin' ]; then
    open "$1"
  elif [ "$(expr substr $(uname -s) 1 5)" == "Linux" ]; then
    xdg-open "$1"
  else
    echo -e "${RED}Error: Sorry, opening files is not supported for your OS.${NC}"
  fi
}

readIniFile () { # expects one argument: absolute path of profiles.ini
  declare -r inifile="$1"
  declare -r tfile=$(mktemp)

  if [ $(grep '^\[Profile' "$inifile" | wc -l) == "1" ]; then ### only 1 profile found
    grep '^\[Profile' -A 4 "$inifile" | grep -v '^\[Profile' > $tfile
  else
    grep -E -v '^\[General\]|^StartWithLastProfile=|^IsRelative=' "$inifile"
    echo ''
    read -p 'Select the profile number ( 0 for Profile0, 1 for Profile1, etc ) : ' -r
    echo -e "\n"
    if [[ $REPLY =~ ^(0|[1-9][0-9]*)$ ]]; then
      grep '^\[Profile'${REPLY} -A 4 "$inifile" | grep -v '^\[Profile'${REPLY} > $tfile
      if [[ "$?" != "0" ]]; then
        echo "Profile${REPLY} does not exist!" && exit 1
      fi
    else
      echo "Invalid selection!" && exit 1
    fi
  fi

  declare -r profpath=$(grep '^Path=' $tfile)
  declare -r pathisrel=$(grep '^IsRelative=' $tfile)

  rm "$tfile"

  # update global variable
  if [[ ${pathisrel#*=} == "1" ]]; then
    PROFILE_PATH="$(dirname "$inifile")/${profpath#*=}"
  else
    PROFILE_PATH="${profpath#*=}"
  fi
}

getProfilePath () {
  declare -r f1=~/Library/Application\ Support/Firefox/profiles.ini
  declare -r f2=~/.mozilla/firefox/profiles.ini
  # [fix] check windows path for t-bird
  declare -r f3=~/Library/Application\ Support/Thunderbird/profiles.ini
  declare -r f4=~/.mozilla/thunderbird/profiles.ini

  if [ "$PROFILE_PATH" = false ]; then
    PROFILE_PATH="$SCRIPT_DIR"
  elif [ "$PROFILE_PATH" = 'list' ]; then
    local ini=''
    if [[ -f "$f1" ]]; then
      ini="$f1"
    elif [[ -f "$f2" ]]; then
      ini="$f2"
    elif [[ -f "$f3" ]]; then
      ini="$f3"
    elif [[ -f "$f4" ]]; then
      ini="$f4"
    else
      echo -e "${RED}Error: Sorry, -l is not supported for your OS${NC}"
      exit 1
    fi
    readIniFile "$ini" # updates PROFILE_PATH or exits on error
  #else
    # PROFILE_PATH already set by user with -p
  fi
}

#########################
#   Update updater.sh   #
#########################

# Returns the version number of a updater.sh file
get_updater_version () {
  echo $(sed -n '5 s/.*[[:blank:]]\([[:digit:]]*\.[[:digit:]]*\)/\1/p' "$1")
}

# Update updater.sh
# Default: Check for update, if available, ask user if they want to execute it
# Args:
#   -donotupdate: New version will not be looked for and update will not occur
#   -update: Check for update, if available, execute without asking
update_updater () {
  if [ $UPDATE = 'no' ]; then
    return 0 # User signified not to check for updates
  fi

  declare -r tmpfile=$(download_file "${UPDATERJS}")

  if [[ $(get_updater_version "${SCRIPT_DIR}/updater.sh") < $(get_updater_version "${tmpfile}") ]]; then
    if [ $UPDATE = 'check' ]; then
      echo -e "There is a newer version of updater.sh available. ${RED}Update and execute Y/N?${NC}"
      read -p "" -n 1 -r
      echo -e "\n\n"
      if [[ $REPLY =~ ^[Nn]$ ]]; then
        return 0 # Update available, but user chooses not to update
      fi
    fi
  else
    return 0 # No update available
  fi
  mv "${tmpfile}" "${SCRIPT_DIR}/updater.sh"
  chmod u+x "${SCRIPT_DIR}/updater.sh"
  "${SCRIPT_DIR}/updater.sh" "$@" -d
  exit 1
}

#########################
#    Update user.js     #
#########################

# Returns version number of a user.js file
get_userjs_version () {
  if [ -e $1 ]; then
    echo "$(sed -n '4p' "$1")"
  else
    echo "Not detected."
  fi
}

add_override () {
  input=$1
  if [ -f "$input" ]; then
    echo "" >> user.js
    cat "$input" >> user.js
    echo -e "Status: ${GREEN}Override file appended:${NC} ${input}"
  elif [ -d "$input" ]; then
    FSAVEIFS=$IFS
    IFS=$'\n\b' # Set IFS
    FILES="${input}"/*.js
    for f in $FILES
    do
      add_override "$f"
    done
    IFS=$SAVEIFS # restore $IFS
  else
    echo -e "${ORANGE}Warning: Could not find override file:${NC} ${input}"
  fi
}

remove_comments () { # expects 2 arguments: from-file and to-file
  sed -e 's/^[[:space:]]*\/\/.*$//' -e '/^\/\*/,/\*\//d' -e '/^[[:space:]]*$/d' -e 's/);[[:space:]]*\/\/.*/);/' "$1" > "$2"
}

# Applies latest version of user.js and any custom overrides
update_userjs () {
  declare -r newfile=$(download_file "${USERJS}")

  echo 'Please observe the following information:'
  echo -e "\t${APPNAME} profile : ${ORANGE}$(pwd)${NC}"
  echo -e "\tAvailable online   : ${ORANGE}$(get_userjs_version $newfile)${NC}"
  echo -e "\tCurrently using    : ${ORANGE}$(get_userjs_version user.js)\n${NC}\n"

  if [ $CONFIRM = 'yes' ]; then
    echo -e "This script will update to the latest user.js file and append any custom configurations from user-overrides.js. ${ORANGE}Continue Y/N? ${NC}"
    read -p "" -n 1 -r
    echo -e "\n"
    if [[ $REPLY =~ ^[Nn]$ ]]; then
      echo -e "${RED}Process aborted${NC}"
      rm $newfile
      return 1
    fi
  fi

  # Copy a version of user.js to diffs folder for later comparison
  if [ "$COMPARE" = true ]; then
    mkdir -p userjs_diffs
    cp user.js userjs_diffs/past_user.js &>/dev/null
  fi

  # backup user.js
  mkdir -p userjs_backups
  local bakname="userjs_backups/user.js.backup.$(date +"%Y-%m-%d_%H%M")"
  if [ $BACKUP = 'single' ]; then
    bakname='userjs_backups/user.js.backup'
  fi
  cp user.js "$bakname" &>/dev/null

  mv "${newfile}" user.js
  echo -e "Status: ${GREEN}user.js has been backed up and replaced with the latest version!${NC}"

  if [ "$ESR" = true ]; then
    sed -e 's/\/\* \(ESR[0-9]\{2,\}\.x still uses all.*\)/\/\/ \1/' user.js > user.js.tmp && mv user.js.tmp user.js
    echo -e "Status: ${GREEN}ESR related preferences have been activated!${NC}"
  fi

  # apply overrides
  if [ "$SKIPOVERRIDE" = false ]; then
    while IFS=',' read -ra FILE; do
      add_override "$FILE"
    done <<< "$OVERRIDE"
  fi

  # create diff
  if [ "$COMPARE" = true ]; then
    pastuserjs='userjs_diffs/past_user.js'
    past_nocomments='userjs_diffs/past_userjs.txt'
    current_nocomments='userjs_diffs/current_userjs.txt'

    remove_comments $pastuserjs $past_nocomments
    remove_comments user.js $current_nocomments

    diffname="userjs_diffs/diff_$(date +"%Y-%m-%d_%H%M").txt"
    diff=$(diff -w -B -U 0 $past_nocomments $current_nocomments)
    if [ ! -z "$diff" ]; then
      echo "$diff" > "$diffname"
      echo -e "Status: ${GREEN}A diff file was created:${NC} ${PWD}/${diffname}"
    else
      echo -e "Warning: ${ORANGE}Your new user.js file appears to be identical.  No diff file was created.${NC}"
      if [ $BACKUP = 'multiple' ]; then
        rm $bakname &>/dev/null
      fi
    fi
    rm $past_nocomments $current_nocomments $pastuserjs &>/dev/null
  fi

  if [ "$VIEW" = true ]; then open_file "${PWD}/user.js"; fi
}

#########################
#        Execute        #
#########################

if [ $# != 0 ]; then
  readonly legacy_lc=$(echo $1 | tr '[A-Z]' '[a-z]')
  # Display usage if first argument is -help or --help
  if [ $1 = '--help' ] || [ $1 = '-help' ]; then
    usage
  elif [ $legacy_lc = '-donotupdate' ]; then
    UPDATE='no'
    legacy_argument $1
  elif [ $legacy_lc = '-update' ]; then
    UPDATE='yes'
    legacy_argument $1
  else
    while getopts ":hp:ludsno:bcvre" opt; do
      case $opt in
        h)
          usage
          ;;
        p)
          PROFILE_PATH=${OPTARG}
          ;;
        l)
          PROFILE_PATH='list'
          ;;
        u)
          UPDATE='yes'
          ;;
        d)
          UPDATE='no'
          ;;
        s)
          CONFIRM='no'
          ;;
        n)
          SKIPOVERRIDE=true
          ;;
        o)
          OVERRIDE=${OPTARG}
          ;;
        b)
          BACKUP='single'
          ;;
        c)
          COMPARE=true
          ;;
        v)
          VIEW=true
          ;;
        e)
          ESR=true
          ;;
        r)
          tfile=$(download_file "${USERJS}")
          mv $tfile "${tfile}.js"
          echo -e "${ORANGE}Warning: user.js was saved to temporary file ${tfile}.js${NC}"
          open_file "${tfile}.js"
          exit 1
          ;;
        \?)
          echo -e "${RED}\n Error! Invalid option: -$OPTARG${NC}" >&2
          usage
          ;;
        :)
          echo -e "${RED}Error! Option -$OPTARG requires an argument.${NC}" >&2
          exit 1
          ;;
      esac
    done
  fi
fi

show_banner
update_updater $@

getProfilePath # updates PROFILE_PATH or exits on error
cd "$PROFILE_PATH" && update_userjs

cd "$CURRDIR"
@dngray

This comment has been minimized.

Copy link
Owner

commented Aug 3, 2019

I'm not sure this will be necessary but thanks anyway.

I only update this when a new stable major release of Thunderbird comes out.

I will then fork the latest stable ghacks-user.js and verify what actually exists within the source code for comm-release, trimming the user.js down to only what actually applies in the current Thunderbird. Some of the options exist but don't actually do anything in the source code because that code does not exist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.