Permalink
Find file
Fetching contributors…
Cannot retrieve contributors at this time
267 lines (221 sloc) 7.5 KB
require 'rubygems'
require 'rake'
require 'rake/clean'
require 'rake/packagetask'
require 'appscript'
require 'tempfile'
require 'yaml'
# base paths
PLUGIN_ROOT = File.expand_path( File.dirname( __FILE__ ) )
PLUGIN_BUNDLE_DIR = File.join( PLUGIN_ROOT, 'bundle' )
PLUGIN_BUILD_DIR = File.join( PLUGIN_ROOT, 'build' )
PLUGIN_TEMPLATE_DIR = File.join( PLUGIN_ROOT, 'templates' )
# plex and PMS paths
DIR_APP_SUPPORT = File.expand_path( '~/Library/Application Support' )
PLEX_SUPPORT_DIR = File.join( DIR_APP_SUPPORT, 'Plex' )
PMS_SUPPORT_DIR = File.join( DIR_APP_SUPPORT, 'Plex Media Server' )
PMS_PLUGIN_DIR = File.join( PMS_SUPPORT_DIR, 'Plug-ins' )
PMS_PLUGIN_DATA_DIR = File.join( PMS_SUPPORT_DIR, 'Plug-in Support' )
PMS_BIN = File.join( PLEX_SUPPORT_DIR, 'Plex Media Server.app', 'Contents', 'MacOS', 'Plex Media Server' )
class File
def self.binary?( name )
fstat = stat( name )
if !fstat.file?
false
else
open( name ) do |file|
blk = file.read( fstat.blksize )
blk.size == 0 || blk.count( "^ -~", "^\r\n" ) / blk.size > 0.3 || blk.count( "\x00" ) > 0
end
end
end
def self.rm_if_exists( name )
rm_rf name if self.exists? name
end
end
def add_env env, bundle_dir
File.open( File.join( bundle_dir, 'Contents', 'env' ), 'w' ) do |f|
f.write env.to_s
end
end
def bundle_name config
( config['PLUGIN_BUNDLE_NAME'] ? config['PLUGIN_BUNDLE_NAME'] : config['PLUGIN_NAME'] ) + '.bundle'
end
def erb config, file
warning = <<-eow
DO NOT EDIT THIS FILE
It was generated from a template. Your changes will be overwritten
eow
comment = case File.extname( file ).sub( /^\./, '' ).to_sym
when :html, :xml, :plist then ['<!--', '-->']
when :py then ['"""', '"""']
when :rb then ['=begin', '=end']
end
temp = Tempfile.new( "erb" )
temp << '<?xml version="1.0" encoding="UTF-8"?>' << "\n" if File.extname( file ) === ".xml"
temp << [comment.first, warning].join( "\n" ) << comment.last << "\n"
File.open( file ).each_line do |line|
temp << line.gsub( /<%=(.*?)%>/ ) do
prop = $1.strip
if value = config[prop]
value
else
raise "couldn't find property `#{prop}' (in #{file})"
end
end
end
temp.close
mv( temp.path, file, :verbose => false )
end
def load_config env=:release
YAML.load_file( File.join( PLUGIN_BUNDLE_DIR, 'Contents', 'config.yml' ) )[env.to_s]
end
config = load_config
PLUGIN_PACKAGE_NAME = "#{config['PLUGIN_NAME']}-#{config['PLUGIN_VERSION']}".gsub " ", "_"
# files to blow away with a `rake clobber`
CLOBBER.include( PLUGIN_BUILD_DIR, "#{PLUGIN_PACKAGE_NAME}.tar.gz" )
task :default => :build
namespace :build do
def build_templates config, build_dir
FileList[ File.join( PLUGIN_TEMPLATE_DIR, '**', '*' ) ].each do |file|
if File.file? file
dest_dir = File.join build_dir, File.dirname( file[PLUGIN_TEMPLATE_DIR.length + 1, file.length] )
dest_file = File.join dest_dir, File.basename( file )
mkdir_p dest_dir
cp file, dest_dir
erb config, dest_file unless File.binary? dest_file
end
end
end
def build env, config
File.rm_if_exists File.join( PLUGIN_BUILD_DIR )
mkdir_p PLUGIN_BUILD_DIR
bundle_dir = File.join( PLUGIN_BUILD_DIR, bundle_name( config ) )
cp_r PLUGIN_BUNDLE_DIR, bundle_dir
add_env env, bundle_dir
FileUtils.rm FileList.new( File.join( PLUGIN_BUILD_DIR, '**', '*.pyc' ) )
readme = Dir["README*"].first
cp_r readme, File.join( PLUGIN_BUILD_DIR, "README.txt" ) if readme
end
desc 'Build a dev distribution.'
task :development do
build_templates load_config( :development ), PLUGIN_BUNDLE_DIR
build :development, load_config( :development )
end
task :dev => :development
desc 'Build a release distribution.'
task :release do
build :release, config
build_templates config, File.join( PLUGIN_BUILD_DIR, bundle_name( config ) )
end
end
desc 'Alias for build:release'
task :build => 'build:release'
namespace :package do
def package config
Appscript.app("AppMaker").activate
se = Appscript.app("System Events")
am = se.processes["AppMaker"]
am_window = am.windows["AppMaker"]
am_window.actions["AXRaise"].perform
[ File.join( PLUGIN_BUILD_DIR, bundle_name( config ) ),
config['PLUGIN_NAME'],
config['PLUGIN_AUTHOR'],
config['PLUGIN_VERSION'],
config['PLUGIN_DESCRIPTION']
].each_with_index do |value, i|
i += 1
am_window.text_fields[i].value.set( value.to_s )
am_window.text_fields[i].focused.set( true )
if i == 1
am_window.text_fields[i].actions["AXConfirm"].perform
else
am_window.text_fields[i].key_code( 124 )
am_window.text_fields[i].keystroke( " \b" )
end
end
am_window.UI_elements["Create Package"].click
am.keystroke( "g", :using => [ :command_down, :shift_down ] )
am.keystroke( PLUGIN_BUILD_DIR + "\r" )
am.keystroke( ( config['PLUGIN_NAME'] + "-" + config['PLUGIN_VERSION'].to_s ).gsub( " ", "_" ) + "\r" )
# wait for save
am_window.text_fields[1].focused.set( true )
Appscript.app("AppMaker").quit
end
desc 'Create a dev-mode, installable plex app'
task :development => 'build:development' do
package load_config( :development )
end
task :dev => :development
desc 'Create an installable plex app'
task :release => 'build:release' do
package config
end
end
task :package => 'package:release' do
end
namespace :pms do
task :restart => [ :stop, :start ]
desc 'Start Plex Media Server'
task :start do
exec '"' + PMS_BIN + '"'
end
task :stop do
system "killall", "Plex Media Server"
end
end
task :pms => 'pms:restart'
namespace :install do
desc 'Install a clean copy (do an uninstall:hard first)'
task :clean => [ 'uninstall:hard', :install ]
desc 'Install a development version of the plugin'
task :development => [ 'build:development', :uninstall ] do
config = load_config :development
ln_s PLUGIN_BUNDLE_DIR, File.join( PMS_PLUGIN_DIR, bundle_name( config ) )
add_env :development, PLUGIN_BUNDLE_DIR
end
task :dev => :development
desc 'Install a release version of the plugin'
task :release => [ 'build:release', :uninstall ] do
mkdir_p File.join( PMS_PLUGIN_DIR, bundle_name( config ) )
cp_r File.join( PLUGIN_BUILD_DIR, bundle_name( config ) ), PMS_PLUGIN_DIR
add_env :release, PLUGIN_BUNDLE_DIR
end
end
desc 'Alias for install:release'
task :install => 'install:release'
namespace :uninstall do
desc 'Remove the installed bundle, but leave data behind.'
task :soft do
File.rm_if_exists File.join( PMS_PLUGIN_DIR, bundle_name( config ) )
end
desc 'Remove the installed bundle and data.'
task :hard => :soft do
files = FileList[
File.join( PMS_PLUGIN_DATA_DIR, "*", "#{config['PLUGIN_ID']}.*" ),
File.join( PMS_PLUGIN_DATA_DIR, "*", "#{config['PLUGIN_ID']}" ),
]
rm_rf files unless files.empty?
end
end
desc 'Alias for uninstall:soft'
task :uninstall => 'uninstall:soft'
namespace :tail do
logs = {
:plex => [ 'Plex', File.expand_path( "~/Library/Logs/Plex.log" ) ],
:plugin => [ 'the plugin', File.expand_path( "~/Library/Logs/PMS Plugin Logs/#{config['PLUGIN_ID']}.log" ) ]
}
def tail logs
system "tail -f " << logs.collect { |log| "\"#{log}\"" }.join( ' ' )
end
logs.each do |k,v|
desc "Tail #{v[0]}'s log file"
task( k ) { tail [v[1]] }
end
desc 'Tail log files'
task :all do
tail logs.collect { |k,v| v[1] }
end
end
desc 'Alias for tail:all'
task :tail => 'tail:all'