Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Create a Time Machine-like feature for Safari tabs Web Browsers
Safari's new 'Reopen All Windows From Last Session' feature is great, but it needs to be improved upon. For example, I usually have a lot of windows with a lot of tabs. Unfortunately, if I start up Safari and then close it down without first clicking 'Reopen All Windows From Last Session,' well, my last session is now a single window. What I want is something like Time Machine for Safari.

I have been using the following method (posted on my blog) for several months. Basically, the process involves creating a script and a LaunchAgent to run the script. I hope that this helps others as much as it has helped me!

[robg adds: Read the rest of the article for the how-to from the author's blog -- however, this is here primarily as backup, in case the original blog post ever vanishes. Any changes to the original post won't be reflected here, but read on for the write-up as it appeared on the author's blog as of the publication date of this hint. Everything that appears below are the author's original words, not mine. I've only edited for layout and display, not content.]

Fortunately, the solution was pretty easy, it just required getting my hands dirty.

Difficulty: Moderate to Hard
Requires: Terminal

Poking around in the Safari directory, in ~/Libaray/Safari, I noticed that there was a file named LastSession.plist. That took all of 10 seconds!

So what I needed was something that would notice when this file had changed and copy it to a directory. I created a file named com.cannasoftware.lastsessiontimemachine.sh in the directory ~/Libaray/Safari with the following contents: Basically it says "make a directory, if it doesn't exist, named LastSessionTimeMachine and then copy the LastSession.plist to a file into that directory and name that file LastSession-year-month-day-hour-minute-second.plist. That's all.

Writing a script to copy the file was easy, but what I needed was something that would run the script. Agents to the rescue! An agent runs in the background and can do many things, one of which is stare at a file to see if it changes and if it does, to do something. In this case, we tell it to stare at the file LastSession.plist and when it changes, to execute our script.

To do this, I created the file com.cannasoftware.lastsessiontimemachine.plist in the directory ~/Library/LaunchAgents with the following contents: WARNING: Be sure to change USERNAME to the user name of your home directory. If you don't, this agent will not work!

TIME FOR A TEST DRIVE

Assuming everything is running, start up Safari and open multiple windows with multiple tabs. Now shut down Safari. If you examine directory ~/Libaray/Safari you should see a new directory named LastSessionTimeMachine. In that directory will be a file named LastSession-year-month-day-hour-minute-second (for example, LastSession-2008-07-31-7-58-32.plist).

That's it!

WHEN TO USE IT

Start up Safari and Reopen All Windows From Last Session. Everything should be fine. Assuming everything is working, shut down Safari. Start up Safari again, but don't click Reopen All Windows From Last Session. Shut down Safari. Start it up again and Reopen All Windows From Last Session. You should get a single window (or no window). Shut down Safari.

Using the Terminal, go to ~/Library/Safari/LastSessionTimeMachine and pick a time when you had multiple windows. Copy that file with the following (example):
cp LastSession-2008-07-31-7-58-32.plist ../LastSession.plist
Start Safari up and click Reopen All Windows From Last Session. You should be greeted with multiple windows and tabs again.

[robg adds: I haven't tested this one.]
    •    
  • Currently 2.11 / 5
  You rated: 3 / 5 (9 votes cast)
 
[13,020 views]  

Create a Time Machine-like feature for Safari tabs | 15 comments | Create New Account
Click here to return to the 'Create a Time Machine-like feature for Safari tabs' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Create a Time Machine-like feature for Safari tabs
Authored by: bkemper on Aug 05, '08 08:16:41AM

Sounds like a great hint. It would be even better if it wrote the previous sessions into a spot in my bookmarks bar though. Then I wouldn't have to Quit Safari and run to the terminal in order to access previous days last-open locations; I could just click on a link in the bookmarks bar, open up the menu for the day I want, and then "open in Tabs".



[ Reply to This | # ]
Create a Time Machine-like feature for Safari tabs
Authored by: feloneouscat on Aug 05, '08 09:23:06AM

I agree, it would be nicer if it were integrated into Safari. It is my hope that either Apple or some enterprising soul will do this.

For myself, I just needed a backup for those "just in case" moments.



[ Reply to This | # ]
Create a Time Machine-like feature for Safari tabs
Authored by: bkemper on Aug 06, '08 07:38:20AM

So there is no way to write the links to the bookmark file instead?



[ Reply to This | # ]
Create a Time Machine-like feature for Safari tabs
Authored by: feloneouscat on Aug 08, '08 08:17:59AM

That's not what I was saying, what I was saying is that this hint was for creating a backup.

Some clever soul could probably create a bookmark that does what you ask with sed or awk quite easily. However it is outside the scope of this article.



[ Reply to This | # ]
Create a Time Machine-like feature for Safari tabs
Authored by: qwerty denzel on Aug 05, '08 04:20:35PM

There's a typo: Libaray above in some of the paths should be Library.



[ Reply to This | # ]
Typos (hopefully) have all been fixed
Authored by: feloneouscat on Aug 08, '08 08:21:05AM

In the link to my website.



[ Reply to This | # ]
Doesn't work for me
Authored by: halbtuerke on Aug 06, '08 03:39:56AM

Nice hint but unfortunately it does not work for me. I have done everything stated in the tutorial but it won't make automatic backups of the LastSession.plist.



[ Reply to This | # ]
Doesn't work for me
Authored by: feloneouscat on Aug 08, '08 08:07:42AM
Hmmm... two possibilities:

If you aren't familiar with shell scripting, you need to do the following:

sudo chmod 755 com.cannasoftware.lastsessiontimemachine.sh

Test it with the following:

./com.cannasoftware.lastsessiontimemachine.sh

If that works, then it is a typo in the Launch Agent. I've had no end of trouble with these buggers.

[ Reply to This | # ]
Don't need sudo...
Authored by: feloneouscat on Aug 08, '08 08:13:25AM

Should be able to chmod...



[ Reply to This | # ]
Create a Time Machine-like feature for Safari tabs
Authored by: S on Aug 07, '08 08:54:42AM
If someone wants to write it to a bookmark, the file is, surprisingly enough, ~/Library/Bookmarks.plist. The structure is pretty simple, but not something I'd want to attempt to write to myself.

[ Reply to This | # ]
wasteful design
Authored by: nyarlathotep on Sep 05, '08 09:20:38AM

Seems naive & wasteful copying LastSession.plist. I mean, what about all those times when the file is the same?

You should use rcs instead. It'll only store data when LastSession.plist changes. And only store the changes. Ideally you should increment the major version number whenever Safari's pid changed.

You could also write history browser using an xml parser to extract the data for individual specific revisions, thus allowing the user browse their history.



[ Reply to This | # ]
Create a Time Machine-like feature for Safari tabs
Authored by: morespace54 on Sep 05, '08 12:59:47PM

How about some sort of (Apple) script that would run on Safari shutdown with a prompt asking you if you want to "Add bookmark for These X Tabs" within a folder named "yyyy-mm-dd-ss"? Anyone?



[ Reply to This | # ]
Create a Time Machine-like feature for Safari tabs
Authored by: douglsmith on Sep 16, '08 11:34:50AM

I tend to keep Safari running with a lot of tabs open so this has been working great for me.

This does leave a large number of files in that folder over time so I added a line to the shell script to delete any files more than a week old:

find ~/Library/Safari/LastSessionTimeMachine -name 'LastSession*' -type f -ctime +7 -delete

Now it does housecleaning each time a new backup is added to the folder. You can change the +7 to a different number of days to suit your needs.



[ Reply to This | # ]
Create a Time Machine-like feature for Safari tabs
Authored by: emailboy on Dec 02, '10 02:46:18PM

I found that, on 10.5.8, I was getting slews of launchd errors about the job respawning too quickly, so I added some keys to the launchd.plist to set KeepAlive false. I also added some comments to the script and set the expiration period to 30 days (personal preference), and added some logging to /tmp (just for safety):

Here's an updated ~/Library/LaunchAgents/com.cannasoftware.lastsessiontimemachine.plist file:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Disabled</key>
    <false/>
    <key>Label</key>
    <string>com.cannasoftware.com.lastsessiontimemachine</string>
    <key>OnDemand</key>
    <true/>
    <key>KeepAlive</key>
    <false/>
    <key>ProgramArguments</key>
    <array>
        <string>/Users/USERNAME/Library/Safari/com.cannasoftware.lastsessiontimemachine.sh</string>
    </array>
    <key>WatchPaths</key>
    <array>
        <string>/Users/USERNAME/Library/Safari/LastSession.plist</string>
    </array>
    <key>StandardErrorPath</key>
        <string>/tmp/lastsessiontimemachine.log</string>
    <key>StandardOutPath</key>
        <string>/tmp/lastsessiontimemachine.log</string>
</dict>
</plist>

And, here's an updated ~/Library/Safari/com.cannasoftware.lastsessiontimemachine.sh file:



#!/bin/bash

#
# Script to create backup copy of Safari's "Last Session" state, to
# protect against accidently quitting Safari without clicking
# "Reopen all windows from last session".
#
# Script is run by LaunchAgent in ~/Library/LaunchAgents directory
# with LastSession.plist as watchfile.
#

#
# Create "LastSessionTimeMachine" directory if it doesn't exist
#
mkdir -p ~/Library/Safari/LastSessionTimeMachine

#
# Copy Safari's last session state file to the "LastSessionTimeMachine"
# directory, with current date and time appended.
#
cp ~/Library/Safari/LastSession.plist \
    ~/Library/Safari/LastSessionTimeMachine/LastSession`date "+-%Y-%m-%d-%H-%M-%S"`.plist

#
# Delete any saved "last session" files which are more than 30 days old
#
find ~/Library/Safari/LastSessionTimeMachine -name 'LastSession*' \
                                             -type f \
                                             -ctime +30 \
                                             -delete

exit 0


[ Reply to This | # ]
Create a Time Machine-like feature for Safari tabs
Authored by: emailboy on Jan 28, '11 04:57:55PM
I found I was getting way too many saved files (as in, thousands and thousands), plus I was still getting launchd errors. I modified the script to keep all of today's files, but only the oldest file from each previous day:

#!/bin/bash

#
# Script to create backup copy of Safari's "Last Session" state, to
# protect against accidently quitting Safari without clicking
# "Reopen all windows from last session".
#
# Script is run by LaunchAgent in ~/Library/LaunchAgents directory
# with LastSession.plist as watchfile.
#

#
# Echo a line to denote start of execution
# (makes it easier when looking in the log)
#
echo "---------- $(date) ----------"

#
# Create "LastSessionTimeMachine" directory if it doesn't exist
#
mkdir -p ~/Library/Safari/LastSessionTimeMachine

#
# Copy Safari's last session state file to the "LastSessionTimeMachine"
# directory, with current date and time appended.
#
DATE=$(date "+-%Y-%m-%d-%H-%M-%S")
cp ~/Library/Safari/LastSession.plist \
    ~/Library/Safari/LastSessionTimeMachine/LastSession${DATE}.plist

# get a list of saved LastSession files, sorted newest to oldest
FILES=$(/bin/ls ~/Library/Safari/LastSessionTimeMachine/LastSession-*.plist | sort -r)

prevYear=0
prevMonth=0
prevDay=0
prevHour=0
prevMin=0
prevSec=0

# get current date
# note: fails if these commands are split across midnight
nowYear=$(date "+%Y")
nowMonth=$(date "+%m")
nowDay=$(date "+%d")

for AFILE in $FILES
do

    # parse filename into timestamp component
    timestamp=$(echo $AFILE | awk -F'[-\.]' '{print $2,$3,$4,$5,$6,$7}')

    # some weird code I found that parses a string into an array    
    set -- "$timestamp" 
    OLDIFS=$IFS; IFS=" "; declare -a Array=($*) 

    year=${Array[0]}
    month=${Array[1]}
    day=${Array[2]}
    hour=$Array
    min=${Array[4]}
    sec=${Array[5]}
        
    # delete file if we already have one from the same day but
    # skip today's files
    if [ "$year"  -eq "$nowYear"   -a \
         "$month" -eq "$nowMonth"  -a \
         "$day"   -eq "$nowDay"    ]; then
        echo "$timestamp is today's"
    elif [                            \
         "$year"  -eq "$prevYear"  -a \
         "$month" -eq "$prevMonth" -a \
         "$day"   -eq "$prevDay" ]; then
        echo "$timestamp is an older previous day's -- deleting"
        rm -f $AFILE
    else
        echo "$timestamp is newest from that day"
    fi
    
    prevYear=$year
    prevMonth=$month
    prevDay=$day
    prevHour=$hour
    prevMin=$min
    prevSec=$sec

done

exit 0



[ Reply to This | # ]