task :build_pkg => :yard
-task :teamcity => [
+task :default => [
:spec,
:yard,
:build_pkg,
require "gpkg/gem_specification"
lib = File.expand_path("../lib", __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
-require "gentex/gems/atv/version"
Gpkg.gem_specification do |gpkg|
gpkg.name = "gems/atv"
- gpkg.version = Gentex::Gems::Atv::VERSION
- gpkg.authors = ["TODO: Write your name"]
- gpkg.email = ["TODO: Write your email address"]
- gpkg.summary = %q{TODO: Write a short summary. Required.}
- gpkg.description = %q{TODO: Write a longer description. Optional.}
+ gpkg.version = "1.0.0"
+ gpkg.authors = ["Mike Lowis"]
+ gpkg.email = ["mike@mdlowis.com"]
+ gpkg.summary = %q{Websocket server that simulates a TV station}
+ gpkg.description = %q{Websocket server that simulates a TV station}
gpkg.homepage = ""
gpkg.licenses = ["Nonstandard"]
gpkg.test_files = gpkg.files.grep(%r{^(test|spec|features)/})
gpkg.require_paths = ["lib"]
- gpkg.add_gpkg_dependency "gpkg", ">= 1.16", "< 99.0"
- gpkg.add_gpkg_development_dependency "gems/teamcity_utils", "~> 1.3"
gpkg.add_development_dependency "json", "~> 2.0"
gpkg.add_development_dependency "rspec", "~> 3.0"
gpkg.add_development_dependency "simplecov", "~> 0.9"
--- /dev/null
+#!/bin/env ruby
+
+require 'atv/database'
+require 'atv/channel'
+require 'atv/player'
+require 'atv/server'
+
+db = ATV::Database.new(ENV["ETV_ROOT"] || "/var/www/atv")
+channels = [
+ ATV::Channel.new('Everything', db,
+ ["Movies", "Shorts", "Shows"])
+]
+player = ATV::Player.new(db, channels)
+server = ATV::Server.new(player)
+server.start
--- /dev/null
+module ATV
+ class Channel
+ def initialize(name, db, selectors = [])
+ @time = 0
+ @index = 0
+ @db = db
+ files = db.files
+ @items = selectors.map do |sel|
+ files.select {|f| f["path"].start_with? sel }
+ end.flatten.shuffle
+ end
+
+ def update(playing)
+ @time += 1 if playing
+ item = @items[@index]
+ if @time >= item["duration"] then
+ next()
+ pp @items[@index]
+ true
+ else
+ false
+ end
+ end
+
+ def next()
+ @time = 0
+ @index += 1
+ if @index >= @items.length
+ @index = 0
+ end
+ end
+ end
+end
--- /dev/null
+require 'json'
+
+module ATV
+ class Database
+ CMD="ffprobe -show_entries format=duration -v quiet -of csv=\"p=0\" -i"
+
+ def initialize(root)
+ @root = root
+ @path = "#{root}/index.json"
+ @data = {}
+ load()
+ end
+
+ def load()
+ if File.exist? @path
+ @data = JSON.parse(File.read(@path))
+ else
+ scan()
+ save()
+ end
+ end
+
+ def save()
+ File.open(@path, "wb") do |f|
+ puts f
+ f.write JSON.dump(@data)
+ end
+ end
+
+ def files
+ @data.keys.map do |f|
+ @data[f].merge({ "path" => f })
+ end
+ end
+
+ def [](key)
+ @data[key]
+ end
+
+ def cleanup()
+ files.each do |f|
+ @db.delete(f) if not File.exist?(f)
+ end
+ end
+
+ def scan()
+ Dir.glob("#{@path}/**/*.{mp4,webm,ogg}").each do |f|
+ next if @data[f]
+ duration = `#{CMD} \"#{f}\"`.chomp.to_f
+ @data[f] = { "duration" => duration }
+ end
+ end
+ end
+end
--- /dev/null
+module ATV
+ class Player
+ def initialize(db, channels)
+ @db = db
+ @channel = 0
+ @channels = channels
+ @playing = true
+ end
+
+ def update()
+ updated = false
+ @channels.each do |c|
+ updated ||= c.update(@playing)
+ end
+ end
+
+ def play()
+ @playing = true
+ end
+
+ def pause()
+ @playing = false
+ end
+
+ def skip()
+ @channels[@channel].next
+ end
+
+ def chan_next()
+ @channel += 1
+ if @channel >= @channels.length then
+ @channel = 0
+ end
+ end
+
+ def chan_prev()
+ @channel -= 1
+ if @channel < 0 then
+ @channel = @channels.length - 1
+ end
+ end
+ end
+end
--- /dev/null
+require 'iodine'
+
+module ATV
+ class Server
+ APP = Proc.new do |env|
+ if env['rack.upgrade?'.freeze] == :websocket
+ env['rack.upgrade'.freeze] = ATV
+ [0,{}, []] # It's possible to set cookies for the response.
+ end
+ end
+
+ def initialize(player)
+ @player = player
+ end
+
+ def start()
+ Iodine.listen(service: :http, handler: APP)
+ Iodine.run_every(1000) do
+ @player.update
+ end
+ Iodine.start
+ end
+ end
+end
+++ /dev/null
-class Database
- CMD="ffprobe -show_entries format=duration -v quiet -of csv=\"p=0\" -i"
-
- def initialize(root)
- @root = root
- @path = "#{root}/index.json"
- @data = {}
- load(path)
- end
-
- def load(path)
- if File.exist? @path
- @data = JSON.parse(File.read(@path))
- end
- end
-
- def save()
- File.open(@path, "wb") do |f|
- f.write JSON.dump(@data)
- end
- end
-
- def reload()
- end
-
- def files
- @data.keys
- end
-
- def [](key)
- @data[key]
- end
-
- def cleanup()
- files.each do |f|
- @db.delete(f) if not File.exist?(f)
- end
- end
-
- def scan()
- Dir.glob("#{@path}/**/*.{mp4,webm,ogg}").each do |f|
- next if @data[f]
- duration = `#{CMD} \"#{f}\"`.chomp.to_f
- @data[f] = { "duration" => duration }
- end
- end
-end
--- /dev/null
+require "atv/database"
+
+describe ATV::Database do
+end
command_name "RSpec"
end
end
-
-require "gentex/gems/atv"