Skip to content

Commit

Permalink
Castanaut 1.0.0 release.
Browse files Browse the repository at this point in the history
  • Loading branch information
Joseph Pearson committed Feb 26, 2008
0 parents commit 75a2570
Show file tree
Hide file tree
Showing 30 changed files with 2,428 additions and 0 deletions.
29 changes: 29 additions & 0 deletions Copyright.txt
@@ -0,0 +1,29 @@
== Castanaut

Copyright (C) 2008 Inventive Labs.

This program is free software. It comes without any warranty, to
the extent permitted by applicable law. You can redistribute it
and/or modify it under the terms of the Do What The Fuck You Want
To Public License, Version 2, as published by Sam Hocevar. See
http://sam.zoy.org/wtfpl/COPYING for more details.

=== DomQuery

The DomQuery implementation is included from the Ext JS distribution, which
uses the MIT license requiring the following copyright and permission
notices. These pertain only to the script/gebys.js file.

Copyright (c) 2006-2007 Ext JS, LLC.

Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use,
copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the
Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
3 changes: 3 additions & 0 deletions History.txt
@@ -0,0 +1,3 @@
== 1.0.0 / 2008-02-21

* Initial release.
31 changes: 31 additions & 0 deletions Manifest.txt
@@ -0,0 +1,31 @@
Copyright.txt
History.txt
Manifest.txt
README.txt
Rakefile
bin/castanaut
cbin/osxautomation
lib/castanaut.rb
lib/castanaut/exceptions.rb
lib/castanaut/keys.rb
lib/castanaut/main.rb
lib/castanaut/movie.rb
lib/castanaut/plugin.rb
lib/plugins/ishowu.rb
lib/plugins/mousepose.rb
lib/plugins/safari.rb
scripts/coords.js
scripts/gebys.js
tasks/ann.rake
tasks/annotations.rake
tasks/doc.rake
tasks/gem.rake
tasks/manifest.rake
tasks/post_load.rake
tasks/rubyforge.rake
tasks/setup.rb
tasks/spec.rake
tasks/svn.rake
tasks/test.rake
test/example_script.screenplay
test/googling.screenplay
161 changes: 161 additions & 0 deletions README.txt
@@ -0,0 +1,161 @@
= Castanaut: Automate your screencasts.

Author: Joseph Pearson
http://gadgets.inventivelabs.com.au/castanaut

== DESCRIPTION:

Castanaut lets you write executable scripts for your screencasts. With a
simple dictionary of stage directions, you can create complex interactions
with a variety of applications. Currently, and for the foreseeable future,
Castanaut supports Mac OS X 10.5 only.

== SYNOPSIS:

=== Writing screenplays

You write your screenplays as Ruby files. Castanaut has been designed to
read fairly naturally to the non-technical, within Ruby's constraints.

Here's a simple screenplay:

launch "Safari", at(10, 10, 800, 600)
type "http://www.inventivelabs.com.au"
hit Enter
pause 2
move to(100, 100)
move to(200, 100)
move to(200, 200)
move to(100, 200)
move to(100, 100)
say "I drew a square!"

With any luck we don't need to explain to you what this screenplay
does. The only thing that might need some explanation is "say" -- this has a
robotic voice speak the given string. (Also: all numbers are pixel
co-ordinates).

About the robot: no, we don't recommend you use this in real screencasts for
a large audience. Most people find it a little offputting.
You are free to contravene our recommendation though. You
can tweak the robot in the Mac OS X Speech Preferences pane.

=== Running your screenplay

Simply give the screenplay to the castanaut command, like this:

castanaut test.screenplay

This assumes you have a screenplay file called "test.screenplay" in the
directory where you are running the command.

Of course, it isn't always convenient to drop to the terminal to run your
screenplay. So there's also a method of executing your screenplays directly.
You need to add this line (the "shebang" line) at the top of your screenplay:

#!/usr/bin/env castanaut

Then you need to set the screenplay to be executable by running this command
on it:

chmod a+x test.screenplay

Again, substitute "test.screenplay" for your screenplay's filename.

At this point, you should be able to double-click the screenplay, or invoke
it with Quicksilver, or run it any other way that floats your boat.

=== Stopping the screenplay

If you want to abruptly terminate execution before the end of the screenplay,
you just need to run the 'castanaut' command again -- with or without any
arguments.

Of course, that might be easier said than done, if you haven't got full
control of the mouse or keyboard at the time. One recommendation is to assign
a system hot-key to invoke castanaut. I use a Quicksilver trigger for this,
assigned to Shift-F1, that calls castanaut. You'll need the full path to
the command for this, which is usually /usr/bin/castanaut, but you can check
it with the following command:

which "castanaut"


=== What stage directions can I make?

Out of the box, Castanaut performs mouse actions, keyboard actions,
robot speech and application launches.

For a complete overview of the built-in stage directions, see the
Castanaut::Movie class.

=== Using plugins

Of course, just using the built-in stage directions is a little bit awkward
and verbose. Plugins allow you to extend the available dictionary with
some additional convenience actions. Typically a plugin is specific to an
application.

Castanaut comes with several plugins, including Castanaut::Plugin::Safari for
interacting with the contents of web-pages, and Castanaut::Plugin::Ishowu for
recording screencasts using the iShowU application from Shiny White Box.

To use a plugin, simply declare it:

plugin "safari"

launch "Safari", at(32, 32, 800, 600)
url "http://www.google.com"
pause 4
move to_element('input[name="q"]')
click
type "Castanaut"
move to_element('input[type="submit"]')
click
pause 4
say "Oh. I was hoping for more results."


In the example above, we use the two methods provided by the Safari module:
url, which causes Safari to navigate to the given url, and to_element, which
returns the co-ordinates of a page element (using CSS selectors) relative to
the screen.

=== Creating your own plugins

Advanced users can create their own plugins. Put them in a directory
called "plugins" below the directory containing the screenplays that use
the plugin.

Take a look at the plugins that Castanaut comes with for examples on creating
your own.

== REQUIREMENTS:

* Mac OS X 10.5

== INSTALL:

Run the following command to install Castanaut

sudo gem install castanaut

Once installed, you should run the following command for two reasons:

castanaut

Reason 1 is to confirm that it is installed correctly. Reason 2 is to set up
the permissions on the utility that controls your mouse and keyboard during
Castanaut movies. You may be asked for a password here.

If you just see a "ScreenplayNotFound" exception here, everything's good.

== LICENSE:

Copyright (C) 2008 Inventive Labs.

Released under the WTFPL: http://sam.zoy.org/wtfpl.

Portions released under the MIT License.

See Copyright.txt for full licensing details.
25 changes: 25 additions & 0 deletions Rakefile
@@ -0,0 +1,25 @@
# Look in the tasks/setup.rb file for the various options that can be
# configured in this Rakefile. The .rake files in the tasks directory
# are where the options are used.

load 'tasks/setup.rb'

ensure_in_path 'lib'
require 'castanaut'

task :default => 'spec:run'

PROJ.name = 'castanaut'
PROJ.authors = 'Joseph Pearson'
PROJ.email = 'joseph@inventivelabs.com.au'
PROJ.url = 'http://castanaut.rubyforge.org'
PROJ.version = Castanaut::VERSION

PROJ.rubyforge_name = 'castanaut'
PROJ.rdoc_remote_dir = 'doc'

PROJ.exclude += ['^spec\/*', '^test\/*']

PROJ.spec_opts << '--color'

# EOF
7 changes: 7 additions & 0 deletions bin/castanaut
@@ -0,0 +1,7 @@
#!/usr/bin/env ruby

require File.expand_path(
File.join(File.dirname(__FILE__), '..', 'lib', 'castanaut')
)

Castanaut::Main.run ARGV
Binary file added cbin/osxautomation
Binary file not shown.
64 changes: 64 additions & 0 deletions lib/castanaut.rb
@@ -0,0 +1,64 @@
# $Id$

# Equivalent to a header guard in C/C++
# Used to prevent the class/module from being loaded more than once
unless defined? Castanaut

# The Castanaut module. For orienting yourself within the code, it's
# recommended you begin with the documentation for the Movie class,
# which is the big one.
#
# Execution typically begins with the Main class.
module Castanaut

# :stopdoc:
VERSION = '1.0.0'
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR

FILE_RUNNING = "/tmp/castanaut.running"
FILE_APPLESCRIPT = "/tmp/castanaut.scpt"
# :startdoc:

# Returns the version string for the library.
#
def self.version
VERSION
end

# Returns the library path for the module. If any arguments are given,
# they will be joined to the end of the libray path using
# <tt>File.join</tt>.
#
def self.libpath( *args )
args.empty? ? LIBPATH : ::File.join(LIBPATH, *args)
end

# Returns the lpath for the module. If any arguments are given,
# they will be joined to the end of the path using
# <tt>File.join</tt>.
#
def self.path( *args )
args.empty? ? PATH : ::File.join(PATH, *args)
end

# Utility method used to rquire all files ending in .rb that lie in the
# directory below this file that has the same name as the filename passed
# in. Optionally, a specific _directory_ name can be passed in such that
# the _filename_ does not have to be equivalent to the directory.
#
def self.require_all_libs_relative_to( fname, dir = nil )
dir ||= ::File.basename(fname, '.*')
search_me = ::File.expand_path(
::File.join(::File.dirname(fname), dir, '**', '*.rb'))

Dir.glob(search_me).sort.each {|rb| require rb}
end

end # module Castanaut

Castanaut.require_all_libs_relative_to __FILE__

end # unless defined?

# EOF
32 changes: 32 additions & 0 deletions lib/castanaut/exceptions.rb
@@ -0,0 +1,32 @@
module Castanaut
# All Castanaut errors are defined within this module. If you are creating
# a plugin, you should re-open this module in your plugin script file to
# add any plugin-specific exceptions (it's also a good idea to have them
# descend from CastanautError).
module Exceptions
# The abstract parent class of all Castanaut errors.
class CastanautError < RuntimeError
end

# Raised if Castanaut was invoked with no screenplay argument, or one
# pointing to a non-existent file.
class ScreenplayNotFound < CastanautError
end

# If Castanaut::Movie#run sees a non-zero exit status from the shell
# process, this error will be raised.
class ExternalActionError < CastanautError
end

# If the FILE_RUNNING flag file is deleted or moved during the execution
# of a movie, it will terminate and raise this exception.
class AbortedByUser < CastanautError
end

# Despite asking for permission, the osxautomation utility in cbin cannot
# be executed. This is pretty fatal to our intentions, so we abort with
# this exception.
class OSXAutomationPermissionError < CastanautError
end
end
end

0 comments on commit 75a2570

Please sign in to comment.