Posts Tagged ‘applescript’

Preview crashes when reopening PDFs created with LaTeX

Sunday, March 17th, 2013

To typeset documents I use pdflatex. I edit my tex files using vim and build the pdfs using a makefile. At the end of my make sequence I like to have:


open my.pdf

Which on my mac causes preview to open my pdf document.

When I recompile and this command runs, sometimes preview just focuses the already open document, but other times it opens a new window. I haven’t backwards engineered how it decides which to do, but it might be correlated with the amount of change in between. In any case, Preview recently has been crashing when it tries to open the same document in a new window. For small, short-term articles this is not so annoying. But now, writing my t****s, I’m really getting frustrated.

I wrote an applescript to replace the open command above. First you’ll need to enable applescript for Preview.app. Then you can save the following in preview.scpt.


on run argv
	set file_name to item 1 of argv
	try
		tell application "Preview"
			activate
			set open_already to false
			repeat with this_doc in every document
				set open_already to open_already or (name of this_doc as string is equal to file_name)
				if open_already then
					return "open already"
				end if
			end repeat
			if not open_already then
				open (do shell script "pwd") & "/" & file_name
				return ""
			end if
		end tell
	on error errMsg
		return errMsg
	end try
end run

You can run with:


osascript preview.scpt my.pdf

The rerun to see that no action is taken.

Scroll a bit in safari window, take screenshot repeat

Friday, February 22nd, 2013

Here’s an applescript I used to make a series of screen captures of scrolling through a web page in safari:


tell application "Safari"
	activate
	set sc to 0
	repeat
		set thescript to "if((window.pageYOffset + window.innerHeight)<document.body.clientHeight)
		{
    	window.scrollBy(0,10); // horizontal and vertical scroll increments
		}"
		do JavaScript thescript in current tab of first window
		set imagePath to (path to desktop as text) & "screenCapture_" & my zero_pad(sc, 6) & ".png"
		delay 1.5
		do shell script "screencapture -o -mx -T0 " & quoted form of POSIX path of imagePath
		delay 0.5
		set sc to sc + 1
	end repeat
	
end tell

on zero_pad(value, string_length)
	set string_zeroes to ""
	set digits_to_pad to string_length - (length of (value as string))
	if digits_to_pad > 0 then
		repeat digits_to_pad times
			set string_zeroes to string_zeroes & "0" as string
		end repeat
	end if
	set padded_value to string_zeroes & value as string
	return padded_value
end zero_pad

Source

Screen capture a remote desktop into the remote clipboard

Friday, January 6th, 2012

I’m working a bit with Apple Remote Desktop now and I’m having trouble taking screen captures. It seems easy to take a screen capture that ends up as a file on or in the clipboard of the client side. But I’d rather be completely immersed in the remote computer, so ideally when I hit CMD+SHIFT+3 I’d get a screen shot the size and resolution of my remote desktop saved to the remote’s clipboard.

Here’s what I’m doing for now. I prepare my app that I want to screen capture then I switch to terminal and issue


echo "tell application \"skinning\" to activate" | osascript - && screencapture -c

This switches to my app and takes a screen capture into the clipboard.

Share internet (via wifi Airport) applescript

Sunday, July 17th, 2011

Here’s an applescript we’ve been using at home to share the ethernet internet connection between our two laptops. The computer with the ethernet cord plugged in runs this script, then the other computer can connect to the wireless network of that computer’s name and share its internet connection.


tell application "System Preferences"
	activate
end tell

tell application "System Events"
	tell process "System Preferences"
		click menu item "Sharing" of menu "View" of menu bar 1
		delay 2
		tell window "Sharing"
			if value of checkbox 1 of row 11 of table 1 of scroll area 1 of group 1 is 1 then
				click checkbox 1 of row 11 of table 1 of scroll area 1 of group 1
				click checkbox 1 of row 11 of table 1 of scroll area 1 of group 1
			end if
			
			
			click checkbox 1 of row 11 of table 1 of scroll area 1 of group 1
			delay 1
			if (exists sheet 1) then
				if (exists button "Turn AirPort On" of sheet 1) then
					click button "Turn AirPort On" of sheet 1
					delay 1
				end if
				click button "Start" of sheet 1
			end if
		end tell
	end tell
	tell application "System Preferences" to quit
end tell

Downloads

ShareInternet.app (zip) Here’s a version wrapped into an app with a nice little icon so you can put it on your dock.

Ignore nytimes paywall with simple client-side javascript, or applescript

Thursday, April 21st, 2011

Today was my first experience with the New York Times paywall. It manifested as an html overlay on top of the article I wanted to read. The article seemed to have fully loaded which made me think that if I could just get rid of the overlay I’d be able to read it.

This turned out to be the exactly case. I just zapped the div containing the overly (properly labeled id='overlay' and restored the overflow of the main page (to get scrolling back).

ignore nytimes paywall

This is easily accomplished with three lines of client side javascript:


document.getElementById('overlay').parentNode.innerHTML = '';
document.body.style['overflow-x'] = 'auto';
document.body.style['overflow-y'] = 'auto';

There are many ways of issuing your own javascript on pages opened in your browser, whatever that might be.

For me on a mac with safari, wrapping the above into a little applescript is easiest. I save this in a file called Ignore-nytimes-paywall.scpt:


tell application "Safari"
	try
		set doc to front document
		do JavaScript "document.getElementById('overlay').parentNode.innerHTML = '';" in doc
		do JavaScript "document.body.style['overflow-x'] = 'auto';" in doc
		do JavaScript "document.body.style['overflow-y'] = 'auto';" in doc
	on error errText number errNum
	end try
end tell

It seems that coming up with your own hack for knocking down the nytimes paywall is the trend these days. We’re all blowing our technological Joshua trumpets ;-) .

Update: I’m now more convinced that nytimes is just using this paywall as an experiment. Ignoring the paywall is even easier than I thought:

Readers need only remove “?gwh=numbers” from the URL. They can also clear their browser caches, or switch browsers as soon as they see the subscription prompt. All three of these simple fixes will let them continue reading.

Source

Update:
Seems the paywall organization has changed a little bit and now the client side javascript should be:


document.getElementById('regiwallBackground').style.display = 'none';
document.getElementById('regiwallOverlay').style.display = 'none';
document.body.parentElement.style.overflow = 'scroll';

List of installed applications on mac

Wednesday, February 23rd, 2011

Seems like there are several hacky ways to achieve this. And it depends on what you mean by “installed”. If you just mean, list all application bundles (files ending with .app) then you can achieve it the following command in your terminal:


find / -name "*.app"

That command returns a list where each line is the full path to the application. If you just want the name of the application then use:


find / -name "*.app" | sed -e "s/\(.*\)\/\([^\/]*\).app/\2/g"

If you’re really a stickler and want to see all applications even ones the current user does not have permissions to see then use:


sudo find / -name "*.app" | sed -e "s/\(.*\)\/\([^\/]*\).app/\2/g"

On my computer this takes around ∞ minutes.

But maybe you don’t mean to find every application anywhere on the computer, but say just the ones in the /Applications folder. Then you can slightly change the above command to:


find /Applications -name "*.app" | sed -e "s/\(.*\)\/\([^\/]*\).app/\2/g"

On my computer this takes around 3 minutes.

Notice that this is still taking a considerable amount of time and its returning a bunch of weird applications. These are Utility applications or example applications buried deep in the sub folders of the /Applications folder. You can speed up the previous command by providing a maximum depth for the search:


find /Applications -name -maxdepth 1 "*.app" | sed -e "s/\(.*\)\/\([^\/]*\).app/\2/g"

This only finds .app files directly in the /Applications folder. So it doesn’t find the Microsoft Office or Adobe CS5 apps I have because those are grouped into a folder. But it only takes 0.050 seconds.

I settled on using -maxdepth 2:


find /Applications -name -maxdepth 2 "*.app" | sed -e "s/\(.*\)\/\([^\/]*\).app/\2/g"

This finds all of my meaningful applications and in only 0.060 seconds. Higher maxdepths found a few more apps but they were weirdo utility/example apps and made the command take over a second.

If you need this list as an applescript list just use the following:


set list_of_installed_apps to paragraphs of (do shell script "find /Applications/ -name \"*.app\" -maxdepth 2| sed -e \"s/\\(.*\\)\\/\\([^\\/]*\\).app/\\2/g\"")

Screen capture into photoshop

Monday, January 10th, 2011

Making figures for our upcoming submission I find my self repetitively taking screen captures of my program and then pasting them into photoshop where I can crop and arrange them. This is a lot of clicking around and switching apps and it’s hard to take a sequence of shots quickly. I could make just write all the screen shots to file and load them into photoshop as a batch. But Photoshop’s batch loader script is slow, so pasting is the fastest way to get all the images as layers and move on to editing.

Here’s a script that stays open with a prompt asking whether to take another screenshot and dump it into the current photoshop document. Replace MYAPP with the name of the app your are trying to screen capture.


repeat
	tell application "MYAPP"
		activate
		display dialog "Screen capture and paste into Photoshop?"
	end tell
	
	do shell script "screencapture -c"
	tell application "Adobe Photoshop CS5"
		activate
		tell current document
			paste
		end tell
	end tell
end repeat

Current window to full size on current display

Wednesday, November 3rd, 2010

There are a lot of “maximize window to window” to fit screen scripts floating around, but most don’t bother with supporting a dual monitor set up. Here’s a script that resizes the frontmost window of the frontmost application to fit the whole screen of the display that the window is currently in (decided by the position of the top left corner):


set main_display_size to get_main_display_size()
set main_display_width to item 1 of main_display_size
set main_display_height to item 2 of main_display_size


set secondary_display_size to get_secondary_display_size()
set secondary_display_width to item 1 of secondary_display_size
set secondary_display_height to item 2 of secondary_display_size

tell application "System Events"
	set frontmostApplication to name of the first process whose frontmost is true
end tell
tell application frontmostApplication
	set old_bounds to bounds of first window
	if ((item 1 of old_bounds) < 0 or (item 1 of old_bounds) > main_display_width or (item 2 of old_bounds) < 0 or (item 2 of old_bounds) > main_display_height) and (secondary_display_width is not equal to -1 and secondary_display_height is not equal to -1) then
		tell application "Finder"
			set desktop_bounds to get bounds of window of desktop
		end tell
		
		set bounds of first window to {item 1 of desktop_bounds, item 2 of desktop_bounds, (item 1 of desktop_bounds) + secondary_display_width, (item 2 of desktop_bounds) + secondary_display_height}
		
	else
		set bounds of first window to {0, 0, main_display_width, main_display_height}
	end if
end tell

on get_main_display_size()
	set command to "/usr/sbin/system_profiler SPDisplaysDataType"
	set output to (do shell script command)
	set AppleScript's text item delimiters to "Resolution: "
	set displays to text items of output
	set i to 2
	repeat ((length of displays) - 1) times
		if (offset of "Main Display: Yes" in (item i of displays)) is not equal to 0 then
			set word_list to words of item i of displays
			set main_display_width to item 1 of word_list
			set main_display_height to item 3 of word_list
		end if
		set i to i + 1
	end repeat
	return {main_display_width as integer, main_display_height as integer}
end get_main_display_size

on get_secondary_display_size()
	set command to "/usr/sbin/system_profiler SPDisplaysDataType"
	set output to (do shell script command)
	set AppleScript's text item delimiters to "Resolution: "
	set displays to text items of output
	set i to 2
	set found to false
	repeat ((length of displays) - 1) times
		if (offset of "Main Display: Yes" in (item i of displays)) is equal to 0 then
			set word_list to words of item i of displays
			set secondary_display_width to item 1 of word_list
			set secondary_display_height to item 3 of word_list
			set found to true
		end if
		set i to i + 1
	end repeat
	if found then
		return {secondary_display_width as integer, secondary_display_height as integer}
	else
		return {-1, -1}
	end if
end get_secondary_display_size

Gather all windows to main display, take 3

Wednesday, November 3rd, 2010

Here’s my new definitive “gather all windows to main display” applescript:


set main_display_size to get_main_display_size()
set main_display_width to item 1 of main_display_size
set main_display_height to item 2 of main_display_size

tell application "System Events"
  set frontmostApplication to name of the first process whose frontmost is true
end tell

tell application "System Events" to set the visible of every process to true

tell application "System Events" to set theApps to (name of every process whose visible is true)
repeat with theApp in theApps
  try
    tell application theApp
      set i to 1
      set stack_x to 0
      set stack_y to 0
      if theApp is "Finder" then
        set real_windows to item 1 of windows
      else
        set real_windows to windows
      end if
      repeat (length of real_windows) times
        try
          set old_bounds to bounds of (window i)
          -- only mess with windows whose top left corner is not on main display
          if (item 1 of old_bounds) < 0 or (item 1 of old_bounds) ≥ main_display_width or (item 2 of old_bounds) < 0 or (item 2 of old_bounds) ≥ main_display_height then
            --      if (item 1 of old_bounds
            set new_x1 to (((item 1 of old_bounds) mod main_display_width) + main_display_width) mod main_display_width
            if new_x1 > main_display_width / 2 then
              set new_x1 to stack_x
              set stack_x to stack_x + 10
            end if
            set new_y1 to (((item 2 of old_bounds) mod main_display_height) + main_display_height) mod main_display_height
            if new_y1 > main_display_height / 2 then
              set new_y1 to stack_y
              set stack_y to stack_y + 10
            end if
            set new_x2 to new_x1 + ((item 3 of old_bounds) - (item 1 of old_bounds))
            if new_x2 > main_display_width then
              set new_x2 to main_display_width
            end if
            set new_y2 to new_y1 + ((item 4 of old_bounds) - (item 2 of old_bounds))
            if new_y2 > main_display_height then
              set new_y2 to main_display_height
            end if
            
            set new_bounds to {new_x1, new_y1, new_x2, new_y2}
            set bounds of (window i) to new_bounds
          end if
        end try
        set i to i + 1
      end repeat
    end tell
  end try
end repeat
-- return focus to original frontmost
tell application frontmostApplication
  activate
end tell

on get_main_display_size()
  set command to "/usr/sbin/system_profiler SPDisplaysDataType"
  set output to (do shell script command)
  set AppleScript's text item delimiters to "Resolution: "
  set displays to text items of output
  set i to 2
  repeat ((length of displays) - 1) times
    if (offset of "Main Display: Yes" in (item i of displays)) is not equal to 0 then
      set word_list to words of item i of displays
      set main_display_width to item 1 of word_list
      set main_display_height to item 3 of word_list
    end if
    set i to i + 1
  end repeat
  return {main_display_width as integer, main_display_height as integer}
end get_main_display_size

Split frontmost application’s frontmost two windows

Wednesday, November 3rd, 2010

Here’s a handy applescript to split your frontmost application’s front most two windows on the main display:


set main_display_size to get_main_display_size()
set main_display_width to item 1 of main_display_size
set main_display_height to item 2 of main_display_size

tell application "System Events"
	set frontmostApplication to name of the first process whose frontmost is true
end tell
tell application frontmostApplication
	set bounds of first window to {0, 0, main_display_width / 2, main_display_height}
	set bounds of second window to {main_display_width / 2, 0, main_display_width, main_display_height}
end tell

on get_main_display_size()
	set command to "/usr/sbin/system_profiler SPDisplaysDataType"
	set output to (do shell script command)
	set AppleScript's text item delimiters to "Resolution: "
	set displays to text items of output
	set i to 2
	repeat ((length of displays) - 1) times
		if (offset of "Main Display: Yes" in (item i of displays)) is not equal to 0 then
			set word_list to words of item i of displays
			set main_display_width to item 1 of word_list
			set main_display_height to item 3 of word_list
		end if
		set i to i + 1
	end repeat
	return {main_display_width as integer, main_display_height as integer}
end get_main_display_size

Note:This only works if you save this an a .scpt script file, not as an application as it will just think itself is the frontmost application and do nothing.