I’ve always wanted to be able to access my iCloud Tabs directly from Editorial, but, unfortunately, due to the lack of an iCloud Tabs API, that’s currently not possible. Last week, however, when I linked to the iCloudTabs for Alfred project by Kevin Marchand and saw that the workflow was based on a bit of Python code, I realized that I could modify his script to find a way to make Editorial read constantly-updated iCloud Tabs from a text file.
What follows is a combination of a server-side script and an Editorial workflow to read and open iCloud Tabs within the app. The system works and I’ve been using it every day for the past week with good results.
There are some requirements:
- A Mac capable of running a Python script in the background. I use a Mac mini with Hazel, and I tested it both on Mountain Lion and Mavericks.
- A text file you can access with a URL. You can put this text file on your FTP server, in your Dropbox, or on a CDN. As long as it’s got a URL you can access from Editorial at the end of the process, it’s fine. I recommend using Dropbox to get started.
- Editorial for iPad. I built the workflow for Editorial, and while it can be further modified and used in other scenarios, I won’t cover those here.
And a clarification: the script doesn’t access your iCloud credentials in any way. iCloud Tabs are stored in a .plist file on OS X, which Python can read and parse. The script doesn’t know anything about iCloud – it just reads a file that contains webpage titles and URLs, plus device names.
If you can keep a Mac running to turn your iCloud Tabs into a text file that later becomes a popover in Editorial, you’ll find the necessary scripts and workflow below.
The Python Script
The script is a simple modification of Kevin’s work, but instead of passing results to Alfred, we build a text file that stores iCloud Tabs as lines. These lines are formatted for Editorial, which means that they contain both a webpage’s title and URL, separated by a tab.
#!/usr/bin/python import os import shutil import tempfile import plistlib import json # Based on Kevin Marchand's iCloudTabs project for Alfred # https://github.com/kmarchand/iCloudTabsAlfredWorkflow # Best used in combination with Editorial for iOS # http://omz-software.com/editorial/index.html # The local path of the file that will store and pass URLs to Editorial or other apps fileLocation = '~/Desktop/alltabs.txt' def create_temporary_copy(path): temp_dir = tempfile.gettempdir() temp_path = os.path.join(temp_dir, 'safari_sync_plist_copy.plist') shutil.copy2(os.path.expanduser(path), temp_path) return temp_path # make a temp copy of the plist file temp_plist = create_temporary_copy( '~/Library/SyncedPreferences/com.apple.Safari.plist') # Use plutil to convert binary plist to xml os.system('plutil -convert xml1 %s' % temp_plist) # Use plistlib to convert plist XML to a dictionary info = plistlib.readPlist(temp_plist) # Clean up (delete) temp file os.remove(temp_plist) # Pull out the device elements from the info dict for easier parsing later devicetabs =  for uid in info['values'].values(): try: devicetabs.append([uid['value']['DeviceName'], uid['value']['Tabs']]) except: pass dev = '' # Create string for text file for i in range(len(devicetabs)): dev += '\n' + '----- ' + str(devicetabs[i].encode('utf-8')) + ' -----' for machine in devicetabs[i]: dev += '\n' + machine['Title'].encode('utf-8') + '\t' + machine['URL'].encode('utf-8') # Write to file outfile = os.path.expanduser(fileLocation) f = open(outfile, 'w') print >> f, dev f.close()
All you need to do to make the script ready for your needs is change the
fileLocation variable on line 14. This determines the local path of the text file (called “alltabs.txt”) that will store your iCloud Tabs. By default, the path is “~/Dropbox/alltabs.txt”.
When you’re using Safari on iOS or OS X, the convenience of iCloud Tabs is that they’re constantly updated by iCloud as you close and open tabs in the browser. I wanted to replicate that in my workflow by ensuring that the text file would always have the latest set of tabs from all iCloud-enabled devices. To do this, you need to find a way to run the script everytime the Safari’s tab file (under “~/Library/SyncedPreferences/com.apple.Safari.plist”) is changed, overwriting the text file with updated tabs.
For my workflow, I let Hazel do this job. Every time the .plist is changed, the text file is updated with new tabs, and because the file name is the same, its URL doesn’t change.
Reading iCloud Tabs from Editorial
In Editorial, all the app needs to do is read lines from the text file and present them in a popover. We can do so with just six actions.
First, Editorial needs to know where iCloud Tabs are stored in the form of a text file. Install the workflow, open the workflow editor, and change the first Set Variable action to the URL of your text file. If you keep your file in Dropbox, you want to use the direct Dropbox URL that displays the contents of the text file in a browser – Editorial will be able to read that.
With the URL, Editorial can run a simple Python script to read each tab from the text file and show all tabs in a popover. Note how the workflow removes duplicate lines from the list of iCloud Tabs – if the same URL is open on multiple devices, Editorial will only show it once.
In the popover, tabs are shown with titles under the device they belong to; to open a tab in the Editorial browser, just tap it. Unfortunately, due to Editorial’s lack of more advanced UI tools, the device names are tappable in the list too, but I made sure they stand out enough to be different from regular tabs.
There’s a probably a more elegant way to store iCloud Tabs in a file and access them with Python (JSON comes to mind), but the simple text file works fine and is fast. I’ve been using the workflow for the past week to re-open webpages I first opened on my Mac and iPhone, and I really like the convenience of having iCloud Tabs available in my text editor and research browser.
Note: The screenshot above shows a beta version of Editorial, currently in testing.