elliottcable-play 4
Sign up to get free protection for your applications and to get access to all the features.
- data/.manifest +7 -0
- data/README.markdown +7 -0
- data/Rakefile.rb +46 -0
- data/bin/play +74 -0
- data/config.example.yaml +12 -0
- data/lib/play/configuration.rb +56 -0
- data/lib/play.rb +48 -0
- data/play.gemspec +36 -0
- metadata +81 -0
data/.manifest
ADDED
data/README.markdown
ADDED
data/Rakefile.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
($:.unshift File.expand_path(File.join( File.dirname(__FILE__), 'lib' ))).uniq!
|
2
|
+
require 'play'
|
3
|
+
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
# =======================
|
7
|
+
# = Gem packaging tasks =
|
8
|
+
# =======================
|
9
|
+
begin
|
10
|
+
require 'echoe'
|
11
|
+
|
12
|
+
task :install => :'package:install'
|
13
|
+
task :package => :'package:package'
|
14
|
+
task :manifest => :'package:manifest'
|
15
|
+
namespace :package do
|
16
|
+
Echoe.new('play', Play::Version) do |g|
|
17
|
+
g.author = ['elliottcable']
|
18
|
+
g.email = ['Play@elliottcable.com']
|
19
|
+
g.summary = 'Playing media LIKE A BOSS'
|
20
|
+
g.url = 'http://github.com/elliottcable/play'
|
21
|
+
g.development_dependencies = ['echoe >= 3.0.2']
|
22
|
+
g.bin_files = ['bin/play']
|
23
|
+
g.manifest_name = '.manifest'
|
24
|
+
g.retain_gemspec = true
|
25
|
+
g.rakefile_name = 'Rakefile.rb'
|
26
|
+
g.ignore_pattern = /^\.git\/|\.gemspec/
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
rescue LoadError
|
31
|
+
desc 'You need the `echoe` gem to package Play'
|
32
|
+
task :package
|
33
|
+
end
|
34
|
+
|
35
|
+
# =========
|
36
|
+
# = Other =
|
37
|
+
# =========
|
38
|
+
desc 'Removes all meta producs'
|
39
|
+
task :clobber => :'package:clobber_package' do
|
40
|
+
`rm -rf #{File.expand_path(File.join( File.dirname(__FILE__), 'meta' ))}`
|
41
|
+
end
|
42
|
+
|
43
|
+
desc 'Check everything over before commiting'
|
44
|
+
task :aok => [:'package:manifest']
|
45
|
+
|
46
|
+
task :ci => []
|
data/bin/play
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
#!/usr/bin/ruby -Ku
|
2
|
+
($:.unshift File.expand_path(File.join( File.dirname(__FILE__), '..', 'lib' )) ).uniq!
|
3
|
+
%w[rubygems optparse fileutils play].each {|dep| require dep }
|
4
|
+
|
5
|
+
ConfigurationDirectory = File.expand_path '~/.play'
|
6
|
+
ConfigurationFile = File.join(ConfigurationDirectory, 'config.yaml')
|
7
|
+
|
8
|
+
Dir[File.join(ConfigurationDirectory, '**.rb')].each {|file| require file }
|
9
|
+
Play::Configuration.default ||= Play::Configuration.load ConfigurationFile if ConfigurationFile
|
10
|
+
|
11
|
+
Banner = "\
|
12
|
+
@#=== `play`
|
13
|
+
It's awesome, and you know it.
|
14
|
+
|
15
|
+
Run `ri Play` for more information.
|
16
|
+
|
17
|
+
@#=-- Usage:
|
18
|
+
`play [options] ~/path/to/a/file`
|
19
|
+
`play [options] A Movie`
|
20
|
+
`play [options] A Show S04E10`
|
21
|
+
`play [options] A Show 4x10`
|
22
|
+
|
23
|
+
@#=-- Options:
|
24
|
+
"
|
25
|
+
|
26
|
+
options = Play::Configuration.new
|
27
|
+
OptionParser.new do |opts|
|
28
|
+
opts.banner = Banner
|
29
|
+
|
30
|
+
opts.on("-p", "--padding PADDING", Integer, "Adjust padding to centre video (all sides)") do |p|
|
31
|
+
[:top, :left, :bottom, :right].each do |side|
|
32
|
+
options[[:padding, side].join('_').intern] = p
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
[:top, :left, :bottom, :right].each do |side|
|
37
|
+
opts.on("-" + side.to_s, "--padding-#{side} PADDING", Integer, "Adjust padding to centre video (#{side} padding only)") do |p|
|
38
|
+
options[[:padding, side].join('_').intern] = p
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
opts.on("-L", "--[no-]latest", "Automatically play the latest available piece of media") do |l|
|
43
|
+
options[:latest] = l
|
44
|
+
end
|
45
|
+
|
46
|
+
opts.on("-s", "--skip-to SPOT", Float, "Start at a specified position in playpack (in seconds)") do |s|
|
47
|
+
options[:spot] = s
|
48
|
+
end
|
49
|
+
|
50
|
+
opts.on_tail("--init", "Create a configuration directory") do
|
51
|
+
FileUtils.mkdir_p ConfigurationDirectory
|
52
|
+
FileUtils.cp_r File.expand_path(File.join(File.dirname(__FILE__), '..', 'config.example.yaml')), ConfigurationFile unless File.file? ConfigurationFile
|
53
|
+
exit
|
54
|
+
end
|
55
|
+
opts.on_tail("--help", "Show this help") do
|
56
|
+
puts opts
|
57
|
+
exit
|
58
|
+
end
|
59
|
+
opts.on_tail("--version", "Show version") do
|
60
|
+
puts "I'm `play` version #{Play::Version}, configured to play media using `#{options[:player]}`!"
|
61
|
+
exit
|
62
|
+
end
|
63
|
+
end.parse!
|
64
|
+
|
65
|
+
# TODO: Abstract this out. This is hardcoded to support television shows'
|
66
|
+
# season and episode numbers, and a specific format for said numbers at that.
|
67
|
+
# That should really be configured in a ~/.play/*.rb file, for any media type.
|
68
|
+
query = ARGV.join(' ')
|
69
|
+
bits = query.match(/^(.*?)(?: (?:(?:S(\d+))?(?:E(\d+))?|(\d*)x(\d*)))?$/i)
|
70
|
+
query = bits[1]
|
71
|
+
season = (bits[2].nil? || bits[2].empty?) ? ((bits[4].nil? || bits[4].empty?) ? nil : bits[4]) : bits[2]
|
72
|
+
episode = (bits[3].nil? || bits[3].empty?) ? ((bits[5].nil? || bits[5].empty?) ? nil : bits[5]) : bits[3]
|
73
|
+
|
74
|
+
Play [query, season, episode], options
|
data/config.example.yaml
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
module Play
|
4
|
+
##
|
5
|
+
# A `play` configuration. Usually loaded from YAML, configured in Ruby, or
|
6
|
+
# passed on the command line.
|
7
|
+
class Configuration
|
8
|
+
|
9
|
+
class << self
|
10
|
+
##
|
11
|
+
# A `Configuration` instance that is referenced when a value is not set.
|
12
|
+
attr_accessor :default
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# Loads a `Configuration`. If given a string, treats it as a file path to a
|
17
|
+
# YAML file from which to load the `Configuration`; if given a Hash, loads
|
18
|
+
# it directly.
|
19
|
+
def self.load arg
|
20
|
+
Configuration.new(arg.is_a?(Hash) ? arg : (YAML.load_file(File.expand_path arg) if File.exist?(File.expand_path arg)))
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Loads a `Configuration`. If given a string, treats it as a file path to a
|
25
|
+
# YAML file from which to load the `Configuration`; if given a Hash, loads
|
26
|
+
# it directly.
|
27
|
+
def self.dump path
|
28
|
+
path = File::expand_path path
|
29
|
+
Dir::mkdir File.dirname(path)
|
30
|
+
File.open(path, File::CREAT|File::TRUNC|File::RDWR, 0644) do |f|
|
31
|
+
f.puts YAML::dump(@settings)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
attr_accessor :settings
|
36
|
+
|
37
|
+
##
|
38
|
+
# Creates a new `Configuration` instance.
|
39
|
+
def initialize arg = nil
|
40
|
+
@settings = arg || Hash.new
|
41
|
+
end
|
42
|
+
|
43
|
+
##
|
44
|
+
# Retrieves a setting from this `Configuration`.
|
45
|
+
def [] key
|
46
|
+
@settings[key] || (Configuration.default == self ? nil : (Configuration.default.nil? ? nil : Configuration.default[key]))
|
47
|
+
end
|
48
|
+
|
49
|
+
##
|
50
|
+
# Sets a setting for this `Configuration`.
|
51
|
+
def []= key, value
|
52
|
+
@settings[key] = value
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
data/lib/play.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'play/configuration'
|
2
|
+
|
3
|
+
##
|
4
|
+
# `Play` is a simple system for playing media from the command line.
|
5
|
+
module Play
|
6
|
+
Version = 4
|
7
|
+
|
8
|
+
##
|
9
|
+
# This method is responsible for ferreting out a particular piece of media,
|
10
|
+
# and playing it.
|
11
|
+
def self.Play parameters, options = Configuration.new
|
12
|
+
query, season, episode = parameters
|
13
|
+
|
14
|
+
files = options[:directories].inject(Array.new) do |acc, dir|
|
15
|
+
options[:extensions].inject(acc) {|acc, ext| acc + Dir[File.expand_path File.join(dir, '**', ['*', ext].join('.'))] }
|
16
|
+
end.select do |file|
|
17
|
+
queries = [[query]]
|
18
|
+
queries << ["#{season}x", "S#{season}", "Season #{season}"] if season
|
19
|
+
queries << ["x#{episode}", "E#{episode}", "Episode #{episode}"] if episode
|
20
|
+
queries.all? {|a| a.any? {|e| file.include? e }}
|
21
|
+
end.reject {|file| file =~ /sample/i }
|
22
|
+
|
23
|
+
raise ArgumentError, "Your query matched nothing" if files.empty?
|
24
|
+
|
25
|
+
if options[:latest]
|
26
|
+
# TODO: This should really parse the episode number and shit.
|
27
|
+
file = files.sort {|f1, f2| File.size(f1) <=> File.size(f2) }.last
|
28
|
+
else
|
29
|
+
files.each.with_index {|file, i| puts "#{i + 1}: #{file}"}
|
30
|
+
print "Please select a number: "
|
31
|
+
file = files[STDIN.gets.chomp.to_i - 1]
|
32
|
+
end
|
33
|
+
|
34
|
+
args = [options[:player], file]
|
35
|
+
args += ['-vf', "expand=" + [:top, :bottom, :left, :right].map {|side| "-" + (options[["padding", side].join('_').intern] || 0).to_s}.join(':')]
|
36
|
+
args += ['-ss', options[:spot].to_s] if options[:spot]
|
37
|
+
system *args
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Sets up the default configuration for `play`.
|
42
|
+
def self.configure &block
|
43
|
+
Configuration.default = Configuration.new &block
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
def Play(*args); Play::Play(*args); end
|
data/play.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{play}
|
5
|
+
s.version = "4"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["elliottcable"]
|
9
|
+
s.date = %q{2009-04-09}
|
10
|
+
s.default_executable = %q{play}
|
11
|
+
s.description = %q{Playing media LIKE A BOSS}
|
12
|
+
s.email = ["Play@elliottcable.com"]
|
13
|
+
s.executables = ["play"]
|
14
|
+
s.extra_rdoc_files = ["bin/play", "lib/play/configuration.rb", "lib/play.rb", "README.markdown"]
|
15
|
+
s.files = ["bin/play", "config.example.yaml", "lib/play/configuration.rb", "lib/play.rb", "Rakefile.rb", "README.markdown", ".manifest", "play.gemspec"]
|
16
|
+
s.has_rdoc = true
|
17
|
+
s.homepage = %q{http://github.com/elliottcable/play}
|
18
|
+
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Play", "--main", "README.markdown"]
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
s.rubyforge_project = %q{play}
|
21
|
+
s.rubygems_version = %q{1.3.1}
|
22
|
+
s.summary = %q{Playing media LIKE A BOSS}
|
23
|
+
|
24
|
+
if s.respond_to? :specification_version then
|
25
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
26
|
+
s.specification_version = 2
|
27
|
+
|
28
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
29
|
+
s.add_development_dependency(%q<echoe>, [">= 0", "= 3.0.2"])
|
30
|
+
else
|
31
|
+
s.add_dependency(%q<echoe>, [">= 0", "= 3.0.2"])
|
32
|
+
end
|
33
|
+
else
|
34
|
+
s.add_dependency(%q<echoe>, [">= 0", "= 3.0.2"])
|
35
|
+
end
|
36
|
+
end
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: elliottcable-play
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: "4"
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- elliottcable
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-04-09 00:00:00 -07:00
|
13
|
+
default_executable: play
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: echoe
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
- - "="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.0.2
|
27
|
+
version:
|
28
|
+
description: Playing media LIKE A BOSS
|
29
|
+
email:
|
30
|
+
- Play@elliottcable.com
|
31
|
+
executables:
|
32
|
+
- play
|
33
|
+
extensions: []
|
34
|
+
|
35
|
+
extra_rdoc_files:
|
36
|
+
- bin/play
|
37
|
+
- lib/play/configuration.rb
|
38
|
+
- lib/play.rb
|
39
|
+
- README.markdown
|
40
|
+
files:
|
41
|
+
- bin/play
|
42
|
+
- config.example.yaml
|
43
|
+
- lib/play/configuration.rb
|
44
|
+
- lib/play.rb
|
45
|
+
- Rakefile.rb
|
46
|
+
- README.markdown
|
47
|
+
- .manifest
|
48
|
+
- play.gemspec
|
49
|
+
has_rdoc: true
|
50
|
+
homepage: http://github.com/elliottcable/play
|
51
|
+
post_install_message:
|
52
|
+
rdoc_options:
|
53
|
+
- --line-numbers
|
54
|
+
- --inline-source
|
55
|
+
- --title
|
56
|
+
- Play
|
57
|
+
- --main
|
58
|
+
- README.markdown
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: "0"
|
66
|
+
version:
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
requirements:
|
69
|
+
- - ">="
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: "1.2"
|
72
|
+
version:
|
73
|
+
requirements: []
|
74
|
+
|
75
|
+
rubyforge_project: play
|
76
|
+
rubygems_version: 1.2.0
|
77
|
+
signing_key:
|
78
|
+
specification_version: 2
|
79
|
+
summary: Playing media LIKE A BOSS
|
80
|
+
test_files: []
|
81
|
+
|