#!/bin/bash # © 2007 ROBO Design # Mihai Şucan # http://www.robodesign.ro # # Last update: 2007-10-06 # Do not use any trailing slash DIR_OP_DEV="${HOME}/opera-dev/linux" DIR_OP_PACK="${HOME}/opera-dev/downloads/linux" DIR_OP_STABLE="${HOME}/bin/opera" MY_PWD="$PWD" MY_SELF="${0##*/}" MY_BUILD=20071006 # upgrade settings UPGRADE_BT=0 # bit torrent metadata UPGRADE_CACHE=0 # copy cache4, cacheOp, opcache, and images (favicons) UPGRADE_COOKIES=1 UPGRADE_MAIL=0 # upgrade the email folder, which includes feeds UPGRADE_PLUGINS=0 # copy the plugins folder, pluginpath.ini, and javapath.txt UPGRADE_WAND=1 # all your stored passwords # DISABLED for safety: this always fixex file paths in all INI files, such that your stable Opera installation will not break (hope so) # UPGRADE_FIX_INI=1 # For more options see the Upgrade_Opera() function. add/remove any files/folders you want copied. # Check folders if [[ ! -d "$DIR_OP_DEV" ]] then echo "Error: Cannot find DIR_OP_DEV: $DIR_OP_DEV"; exit 1 fi if [[ ! -d "$DIR_OP_PACK" ]] then echo "Error: Cannot find DIR_OP_PACK: $DIR_OP_PACK"; exit 1 fi if [[ ! -d "$DIR_OP_STABLE" ]] then echo "Error: Cannot find DIR_OP_STABLE: $DIR_OP_STABLE"; exit 1 fi if [[ "$DIR_OP_STABLE" = "$DIR_OP_DEV" ]] then echo "Error: DIR_OP_STABLE cannot be the same as DIR_OP_DEV!" exit 1 fi if [[ "$DIR_OP_STABLE" = "$DIR_OP_PACK" ]] then echo "Error: DIR_OP_STABLE cannot be the same as DIR_OP_PACK!" exit 1 fi if [[ "$DIR_OP_DEV" = "$DIR_OP_PACK" ]] then echo "Error: DIR_OP_DEV cannot be the same as DIR_OP_PACK!" exit 1 fi # This does minimal checks to determine if a folder contains an Opera installation Check_Opera_Dir() { local DIR_OP="$1" if [[ -z "$DIR_OP" || ! -d "$DIR_OP" ]] then echo "Error: The folder was not found: $DIR_OP" exit 1 fi if [[ -d "${DIR_OP}/profile" && -d "${DIR_OP}/usersettings" ]] then echo "Error: The Opera folder $DIR_OP contains both folders: 'usersettings' and 'profile'. Something is weird." exit 1 fi if [[ ! -f "${DIR_OP}/opera" || ! -f "${DIR_OP}/LICENSE" || ! -f "${DIR_OP}/install.sh" ]] then echo "Error: Opera could not be detected inside the folder: $DIR_OP" exit 1 fi } Check_Opera_Dir "$DIR_OP_STABLE" # Determine the folder of the latest Opera build Find_Opera_Latest() { local LOCAL_PWD="$PWD" cd "$DIR_OP_DEV" local OP_DIRS=(opera*/) local n=${#OP_DIRS[@]} DIR_OP_LATEST=${OP_DIRS[$n-1]} DIR_OP_LATEST="${DIR_OP_DEV}/${DIR_OP_LATEST}" if [[ ! -d "$DIR_OP_LATEST" ]] then echo "Error: The latest Opera build folder could not be found in DIR_OP_DEV: $DIR_OP_DEV" exit 1 fi cd "$DIR_OP_LATEST" DIR_OP_LATEST="$PWD" cd "$LOCAL_PWD" if [[ "$DIR_OP_LATEST" = "$DIR_OP_STABLE" ]] then echo "Error: The latest Opera build folder is the same as DIR_OP_STABLE: $DIR_OP_DEV" echo "The script cannot continue. This is probably an error in the configuration." exit 1 fi Check_Opera_Dir "$DIR_OP_LATEST" } # Remove any profile folders in the given Opera folder Clean_Opera() { local LOCAL_PWD="$PWD" Check_Opera_Dir "$1" if [[ "$DIR_OP_STABLE" = "$1" ]] then echo "Error: You are trying to clean the profile of the stable Opera installation. This is not allowed!" exit 1 fi cd "$1" for cdir in 'usersettings' 'profile' do if [[ ! -d "$cdir" ]] then continue fi # TODO # if [[ -f "${cdir}/lock" ]] # then # echo "Error: This Opera instance is locked: ${1}/${cdir}/lock" # echo "Most likely this Opera instance is already running. I cannot remove the profile!" # exit 1 # fi echo; echo "Are you sure you want to remove the folder '${cdir}' from '${1}' ? Type [y]es or anything else for no." read -r echo; if [[ "$REPLY" != 'y' && "$REPLY" != 'yes' ]] then echo "Operation aborted!" exit 1 fi echo "Deleting $cdir" rm -r "$cdir" done cd "$LOCAL_PWD" } # This extracts an Opera build and optionally runs it Unpack_Opera() { local OP_ARCH="$2" if [[ -z "$OP_ARCH" ]] then echo "Error: No Opera archive specified!" exit 1 fi if [[ ! -f "$OP_ARCH" ]] then echo "Error: The archive was not found: $OP_ARCH" exit 1 fi echo "Extracting $OP_ARCH" if [[ "$OP_ARCH" =~ tar\.bz2$ ]] then tar -C "$DIR_OP_DEV" -xjf "$OP_ARCH" elif [[ "$OP_ARCH" =~ tar\.gz$ ]] then tar -C "$DIR_OP_DEV" -xzf "$OP_ARCH" else echo "Error: File type unrecognized: $OP_ARCH" exit 1 fi mv "$OP_ARCH" "${DIR_OP_PACK}/" echo "Archive moved to $DIR_OP_PACK" local DIR_OP="${OP_ARCH##*/}" DIR_OP="${DIR_OP_DEV}/${DIR_OP%.tar.*}" if [[ ! -d "$DIR_OP" ]] then echo "Warning: The folder of the Opera package could not be determined." else echo "The file was unpacked to: $DIR_OP" Check_Opera_Dir "$DIR_OP" fi # optionally run Opera from the unpacked folder if [[ "$1" = "unpack-run" ]] then echo "Starting Opera" cd "$DIR_OP" ./opera fi } # This function "upgrades" an experimental build. # What it does: the script takes all the profile files from your stable Opera installation and copies them to the experimental build. This is very useful when you want to test experimental builds with "heavy" profiles. The script will modify the INI files changing all the occurances of the stable Opera folder path, replacing them with the path of your experimental build. # WARNING: This script relies on predefined folder paths. Make sure your stable Opera installation profile is in the default location (in 'usersettings' or 'profile'). If your INI files point to external folders for skins, userjs, plugins, mail, menus, toolbars, or styles, then those files will not be copied. The script does not check your INI files for external paths. This will make your experimental build share files with your stable build - most likely will cause damage. Upgrade_Opera() { local DIR_OP="$1" # Find the absolute path to the given folder if [[ -z "$DIR_OP" ]] then DIR_OP="$MY_PWD" else if [[ ! -d "$DIR_OP" ]] then echo "Error: Folder not found: $DIR_OP" exit 1 fi local LOCAL_PWD="$PWD" cd "$DIR_OP" DIR_OP="$PWD" cd "$LOCAL_PWD" fi if [[ "$DIR_OP" = "$DIR_OP_STABLE" ]] then echo "Error: You are trying to upgrade the stable build! You cannot do this." exit 1 fi Check_Opera_Dir "$DIR_OP" if [[ -d "${DIR_OP_STABLE}/profile" ]] then local DIR_PROFILE="${DIR_OP_STABLE}/profile" elif [[ -d "${DIR_OP_STABLE}/usersettings" ]] then local DIR_PROFILE="${DIR_OP_STABLE}/usersettings" else echo "Error: No profile folder found in DIR_OP_STABLE: $DIR_OP_STABLE" exit 1 fi # Determine the Opera version of the experimental build, such that the new profile folder can be created ('usersettings' or 'profile') # hackish ... but it works local OP_VER="${DIR_OP##*/}" if [[ -z "$OP_VER" ]] then OP_VER="$DIR_OP" fi IFS='-' OP_VER=($OP_VER) unset IFS if [[ "${OP_VER[0]}" != 'opera' ]] then echo "Error: The specified target Opera folder name is not of the form opera-N.N-whatever. The script cannot continue." exit 1 fi Clean_Opera "$DIR_OP" # remove any existing profile local -i OP_VER_MAJ="${OP_VER[1]%%.*}" local -i OP_VER_MIN="${OP_VER[1]#*.}" OP_VER_MIN="${OP_VER_MIN:0:1}" if [[ ( "$OP_VER_MAJ" -gt 9 ) || ("$OP_VER_MAJ" -eq 9 && "$OP_VER_MIN" -ge 5 ) ]] then OP_VER='kestrel' else OP_VER='merlin' fi if [[ "$OP_VER" = 'kestrel' ]] then local DIR_NEW='profile' else local DIR_NEW='usersettings' fi DIR_NEW="${DIR_OP}/${DIR_NEW}" # Create the new profile folder and copy the files mkdir "$DIR_NEW" TO_COPY='keyboard:locale:menu:mouse:sessions:skin:styles:thumbnails:toolbar:widgets:userjs:browser.js:contacts.adr:download.dat:global.dat:notes.adr:opcacrt6.dat:opcert6.dat:opera.dir:opera6.adr:opera6.ini:oprand.dat:opssl6.dat:opthumb.dat:override.ini:override_downloaded.ini:search.ini:speeddial.ini:spellcheck.ini:urlfilter.ini:vlink4.dat:widgets.adr' if [[ "$UPGRADE_CACHE" -eq 1 ]] then TO_COPY="${TO_COPY}:cache4:cacheOp:opcache:images" fi if [[ "$UPGRADE_MAIL" -eq 1 ]] then TO_COPY="${TO_COPY}:mail" fi if [[ "$UPGRADE_PLUGINS" -eq 1 ]] then TO_COPY="${TO_COPY}:plugins:pluginpath.ini:javapath.txt" fi if [[ "$UPGRADE_BT" -eq 1 ]] then TO_COPY="${TO_COPY}:bt_metadata" fi if [[ "$UPGRADE_COOKIES" -eq 1 ]] then TO_COPY="${TO_COPY}:cookies4.dat" fi if [[ "$UPGRADE_WAND" -eq 1 ]] then TO_COPY="${TO_COPY}:wand.dat" fi echo "Starting to upgrade Opera: $DIR_OP" echo "Copying files..." IFS=':' TO_COPY=($TO_COPY) for elem in "${TO_COPY[@]}" do if [[ ! -d "${DIR_PROFILE}/${elem}" && ! -f "${DIR_PROFILE}/${elem}" ]] then continue fi echo "Copying $elem" cp -r "${DIR_PROFILE}/${elem}" "${DIR_NEW}/${elem}" done unset IFS echo "Files copied." # DISABLED # if [[ "$UPGRADE_FIX_INI" -eq 1 ]] # then Fix_INI "$DIR_OP_STABLE" "$DIR_OP" if [[ "$UPGRADE_MAIL" -eq 1 && -d "${DIR_NEW}/mail" ]] then Fix_INI "$DIR_OP_STABLE" "$DIR_OP" "*.ini *.txt" "mail" fi # fi echo "Finished upgrading Opera. Make sure you check the result before trying to run Opera." } # This function fixes file paths in Opera INI files Fix_INI() { local LOCAL_PWD="$PWD" local DIR_OP1="$1" # source Opera installation path local DIR_OP2="$2" # destination Opera installation path local FIND_FILES="$3" # which files to change local SUBDIR="$4" # which subdir of the two profiles to process Check_Opera_Dir "$DIR_OP1" Check_Opera_Dir "$DIR_OP2" if [[ "$DIR_OP2" = "$DIR_OP_STABLE" ]] then echo "Error: The destination folder for the INI fixes is the same as DIR_OP_STABLE: ${DIR_OP_STABLE}. This is not allowed. The script will not alter in any way the stable Opera installation." exit 1 fi if [[ "$DIR_OP1" = "$DIR_OP2" ]] then echo "Error: The source and destination folders for the INI fixes are the same: ${DIR_OP1}. This is not allowed." exit 1 fi # Determine the profile folders if [[ -d "${DIR_OP1}/profile" ]] then local DIR_PROFILE1="${DIR_OP1}/profile" elif [[ -d "${DIR_OP1}/usersettings" ]] then local DIR_PROFILE1="${DIR_OP1}/usersettings" else echo "Error: I could not find the profile folder in: $DIR_OP1" exit 1 fi if [[ -d "${DIR_OP2}/profile" ]] then local DIR_PROFILE2="${DIR_OP2}/profile" elif [[ -d "${DIR_OP2}/usersettings" ]] then local DIR_PROFILE2="${DIR_OP2}/usersettings" else echo "Error: I could not find the profile folder in: $DIR_OP2" exit 1 fi if [[ ! -z "$SUBDIR" ]] then local SUBDIR1="${DIR_PROFILE1}/${SUBDIR}" local SUBDIR2="${DIR_PROFILE2}/${SUBDIR}" else local SUBDIR1="$DIR_PROFILE1" local SUBDIR2="$DIR_PROFILE2" fi if [[ ! -d "$SUBDIR2" ]] then echo "Error: The specified SUBDIR could not be found: $SUBDIR2" exit 1 fi if [[ -z "$FIND_FILES" ]] then FIND_FILES="*.ini" fi # Start fixing the files... cd "$SUBDIR2" for FILE_IN in $FIND_FILES do # Skip some files with no important paths case "$FILE_IN" in ( 'search.ini' | 'speeddial.ini' | 'spellcheck.ini' | 'urlfilter.ini' | 'override_downloaded.ini' | signature* ) continue ;; esac if [[ ! -f "$FILE_IN" ]] then continue fi echo "Fixing $FILE_IN" FILE_OUT=".op2.${FILE_IN}" IFS= while read -r do local LINE="${REPLY//$SUBDIR1/$SUBDIR2}" if [[ "$REPLY" = "$LINE" ]] then LINE="${REPLY//$DIR_PROFILE1/$DIR_PROFILE2}" if [[ "$REPLY" = "$LINE" ]] then LINE="${REPLY//$DIR_OP1/$DIR_OP2}" fi fi # Special handling for the 'Mail Root Directory' option in the opera6.ini # For safety this will NEVER be the same as it was in the stable opera6.ini - this is to make sure the experimental Opera does NOT access the same Opera files if [[ "$FILE_IN" = 'opera6.ini' && "$LINE" =~ ^Mail\ Root\ Directory\= ]] then # Skip this line if not upgrading the mail. This way, the experimental build will not have any email if [[ ! "$UPGRADE_MAIL" -eq 1 ]] then continue fi # If the line was not changed in the previous steps, then the mail folder is, most likely, external # The script specifically does not handle this case: it will just skip the line (for safety: no email upgrades) if [[ "$REPLY" = "$LINE" ]] then echo "Warning: Your stable Opera installation is configured to use an external mail folder (outside the profile). This script will not copy the mail folder to the experimental build. Your experimental build will not have any emails." continue fi fi echo "$LINE" done <"$FILE_IN" >"$FILE_OUT" unset IFS rm "$FILE_IN" mv "$FILE_OUT" "$FILE_IN" done cd "$LOCAL_PWD" } case "${1:-''}" in ( 'help' | '-h' | '--help' | 'man' | 'doc' ) echo "Opera2 ($MY_BUILD) script by ROBO Design. http://www.robodesign.ro" echo; echo "Usage:" echo; echo "$MY_SELF clean" echo; echo "This will remove the profile of your latest Opera build. You can configure where experimental builds are located using the DIR_OP_DEV variable." echo; echo "$MY_SELF clean-run" echo; echo "The same as above, but Opera will be started afterwards." echo; echo "$MY_SELF unpack opera-*.tar.bz2/gz" echo; echo "This will unpack the Opera build you want designated by the second argument. The build must be provided as a tar.gz or tar.bz2 file - as the official ones are. The package will moved to the configured DIR_OP_PACK, and the content of the archive will be extracted to your DIR_OP_DEV." echo; echo "$MY_SELF unpack-run opera-*.tar.bz2/gz" echo; echo "The same as above, but the script will also start Opera from the extracted folder." echo; echo "$MY_SELF upgrade opera-*" echo; echo "This will \"upgrade\" the Opera build you want designated by the second argument - a folder name starting with \"opera-\" followed by the major and minor version (this is the default naming of Opera builds). If the second argument is not specified, the current working directory will be used. The script will COPY files from your stable profile folder to the profile of the build you want. The script will also make some changes to several copied files (will replace all paths pointing to the stable Opera installation folder to the new build)." echo "WARNING: Doing this will DELETE the profile of the Opera build specified as the second argument. The script does NOT try to detect if the destination folder is REALLY an experimental build. Do NOT run this on your Opera stable installation folder. Also, you should check the script source ... to be sure it will not break your stable installation. :)" echo "Always check the result of running this script before starting Opera." echo; echo "$MY_SELF any thing else (or no arguments)" echo; echo "This will start the latest Opera build from the configured DIR_OP_DEV with the provided arguments. You can configure other applications to automatically open links with this script - the latest Opera build." ;; ( 'clean' | 'clean-run' ) Find_Opera_Latest Clean_Opera "$DIR_OP_LATEST" if [[ "$1" = 'clean-run' ]] then echo "Starting Opera with a clean profile from: $DIR_OP_LATEST" cd "$DIR_OP_LATEST" ./opera fi ;; ( 'unpack' | 'unpack-run' ) Unpack_Opera "$1" "$2" ;; ( 'upgrade' ) Upgrade_Opera "$2" ;; ( * ) Find_Opera_Latest echo "Starting Opera: $DIR_OP_LATEST" cd "$DIR_OP_LATEST" ./opera $@ ;; esac