class TivoHMO::CLI
The command line interface to tivohmo
Public Class Methods
description()
click to toggle source
# File lib/tivohmo/cli.rb, line 14 def self.description desc = <<-DESC TivoHMO version #{TivoHMO::VERSION} Runs a HMO server. Specify one or more applications to show up as top level shares in the TiVo Now Playing view. The application, identifier, transcoder, metadata options can be given in groups to apply the transcoder and metadata to each application - uses the application's default if not given e.g. tivohmo -t Movies -a TivoHMO::Adapters::Filesystem::Application \\ -i ~/Video/Movies \\ -t "TV Shows" \\ -a TivoHMO::Adapters::Filesystem::Application \\ -i ~/Video/TV to run two top level filesystem video serving apps for different dirs, or tivohmo -t Vids \\ -a TivoHMO::Adapters::Filesystem::Application \\ -i ~/Video to run the single filesystem app, or tivohmo -t PlexVideo \\ -a TivoHMO::Adapters::Plex::Application \\ -i localhost to run the single plex app DESC desc.split("\n").collect(&:strip).join("\n") end
Public Instance Methods
execute()
click to toggle source
# File lib/tivohmo/cli.rb, line 107 def execute if version? puts "TivoHMO Version #{TivoHMO::VERSION}" return end install_tivohmo if install? c = File.expand_path(configuration) if configuration s = File.expand_path(settings) if settings TivoHMO::Config.instance.setup(c, s) setup_logging logger.info "TivoHMO #{TivoHMO::VERSION} starting up" # set any config items passed in on cli configitem_list.each do |item| key, value = item.split('=') Config.instance.set(key, value) end # allow cli option to override config file set_if_default(:port, TivoHMO::Config.instance.get(:port).try(:to_i)) server = TivoHMO::API::Server.new apps = setup_applications apps.each {|app| server.add_child(app) } preload_containers(server) if preload? opts = {} set_if_default(:beacon, TivoHMO::Config.instance.get(:beacon)) if beacon.present? limit, interval = beacon.split(":") opts[:limit] = limit.to_i if limit.present? opts[:interval] = interval.to_i if interval.present? end notifier = TivoHMO::Beacon.new(port, **opts) TivoHMO::Server.start(server, port) do |s| wait_for_server { notifier.start } end end
Private Instance Methods
get_binding(config)
click to toggle source
# File lib/tivohmo/cli.rb, line 270 def get_binding(config) binding end
install_file(src, dst, config={}, sudo=false)
click to toggle source
# File lib/tivohmo/cli.rb, line 274 def install_file(src, dst, config={}, sudo=false) src = File.expand_path(src) dst = File.expand_path(dst) block = Proc.new do |f| template = ERB.new(File.read(src), nil, "-") result = template.result(get_binding(config)) f.write(result) end puts "Installing #{dst}" if sudo sudo_open(dst, "w", &block) else open(dst, "w", &block) end end
install_tivohmo()
click to toggle source
# File lib/tivohmo/cli.rb, line 293 def install_tivohmo puts "Installing TivoHMO" contrib_path = File.expand_path("../../../contrib", __FILE__) case RUBY_PLATFORM when /darwin/ config = { daemon_config: "~/Library/LaunchAgents/tivohmo.plist", configuration: "~/Library/Preferences/tivohmo.yml", logfile: "~/Library/Logs/tivohmo.log", settings: "~/Library/Preferences/tivohmo.runtime.yml" } install_file("#{contrib_path}/tivohmo.yml", config[:configuration], config) install_file("#{contrib_path}/tivohmo.plist", config[:daemon_config], config) puts "TivoHMO installed" puts "To start tivohmo, execute the command:" puts "\tlaunchctl load #{config[:daemon_config]}" puts "To stop tivohmo, execute the command:" puts "\tlaunchctl unload #{config[:daemon_config]}" when /linux/ config = { daemon_config: "/etc/init/tivohmo.conf", configuration: "/etc/tivohmo.yml", logfile: "/var/log/tivohmo.log", settings: "/var/run/tivohmo.runtime.yml" } puts "Sudo password needed to install files" install_file("#{contrib_path}/tivohmo.yml", config[:configuration], config, true) install_file("#{contrib_path}/tivohmo.conf", config[:daemon_config], config, true) puts "TivoHMO installed" puts "To start tivohmo, execute the command:" puts "\tsudo service tivohmo start" puts "To stop tivohmo, execute the command:" puts "\tsudo service tivohmo stop" else $stderr.puts "Unsupported OS: #{RUBY_PLATFORM}" exit(1) end exit(0) end
load_adapter(clazz)
click to toggle source
# File lib/tivohmo/cli.rb, line 185 def load_adapter(clazz) if clazz && clazz.starts_with?('TivoHMO::Adapters::') path = clazz.downcase.split('::')[0..-2].join('/') require path end end
preload_containers(server)
click to toggle source
# File lib/tivohmo/cli.rb, line 240 def preload_containers(server) Thread.new do logger.info "Preloading lazily cached containers" queue = server.children.dup queue.each do |i| logger.debug("Loading children for #{i.title_path}") queue.concat(i.children) end logger.info "Preload complete" end end
set_if_default(attr, new_value)
click to toggle source
# File lib/tivohmo/cli.rb, line 179 def set_if_default(attr, new_value) opt = self.class.find_option("--#{attr}") raise "Unknonwn cli attribute" unless opt self.send("#{attr}=", new_value) if new_value && self.send(opt.read_method) == opt.default_value end
setup_applications()
click to toggle source
# File lib/tivohmo/cli.rb, line 192 def setup_applications app_specs = TivoHMO::Config.instance.get(:applications) || {} title_list.each_with_index do |title, i| app = app_specs[title] app_was_in_config = app.present? app = {} unless app_was_in_config app[:application] = application_list[i] if application_list[i] signal_usage_error "an application class is needed for each application" unless app[:application] app[:identifier] = identifier_list[i] if identifier_list[i] signal_usage_error "an initializer is needed for each application" unless app[:identifier] app[:transcoder] = transcoder_list[i] if transcoder_list[i] app[:metadata] = metadata_list[i] if metadata_list[i] logger.debug "Merged app: #{title} - #{app.inspect}" app_specs[title] = app unless app_was_in_config end signal_usage_error "at least one application is required" unless app_specs.present? apps = app_specs.collect do |title, app_spec| logger.debug "Adding app: #{title} - #{app_spec.inspect}" load_adapter(app_spec[:application]) app_class = app_spec[:application].constantize app = app_class.new(app_spec[:identifier]) app.title = title if app_spec[:transcoder] load_adapter(app_spec[:transcoder]) app.transcoder_class = app_spec[:transcoder].constantize end if app_spec[:metadata] load_adapter(app_spec[:metadata]) app.metadata_class = app_spec[:metadata].constantize end app end apps end
setup_logging()
click to toggle source
# File lib/tivohmo/cli.rb, line 155 def setup_logging set_if_default(:debug, TivoHMO::Config.instance.get(:debug)) Logging.logger.root.level = :debug if debug? set_if_default(:logfile, TivoHMO::Config.instance.get(:logfile)) if logfile.present? appender = Logging.appenders.rolling_file( logfile, truncate: true, age: 'daily', keep: 3, layout: Logging.layouts.pattern( pattern: Logging.appenders.stdout.layout.pattern ) ) # hack to assign stdout/err to logfile if logging to file io = appender.instance_variable_get(:@io) $stdout = $stderr = io Logging.logger.root.appenders = appender end end
sudo_open(path, mode, perms=0755, &block)
click to toggle source
Opens the file for writing by root
# File lib/tivohmo/cli.rb, line 266 def sudo_open(path, mode, perms=0755, &block) open("|sudo tee #{path} > /dev/null", perms, &block) end
wait_for_server() { || ... }
click to toggle source
# File lib/tivohmo/cli.rb, line 252 def wait_for_server Thread.new do while true begin open("http://localhost:#{port}/TiVoConnect?Command=QueryServer") {} yield break rescue Exception => e end end end end