]> git.mdlowis.com Git - proto/atv.git/commitdiff
initial commit of class based arch
authorMichael D. Lowis <mike@mdlowis.com>
Sat, 6 Jan 2024 03:26:18 +0000 (22:26 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Sat, 6 Jan 2024 03:26:18 +0000 (22:26 -0500)
atv/Rakefile.rb
atv/atv.gemspec
atv/bin/atv [new file with mode: 0755]
atv/lib/atv/channel.rb [new file with mode: 0644]
atv/lib/atv/database.rb [new file with mode: 0644]
atv/lib/atv/player.rb [new file with mode: 0644]
atv/lib/atv/server.rb [new file with mode: 0644]
atv/lib/database.rb [deleted file]
atv/spec/database_spec.rb [new file with mode: 0644]
atv/spec/spec_helper.rb

index db1be3b4f68a45eb32dbbf2e3d250d157394edcd..7e2048a1e873776645843160845fe7480a4b3cb7 100644 (file)
@@ -56,7 +56,7 @@ end
 
 task :build_pkg => :yard
 
-task :teamcity => [
+task :default => [
   :spec,
   :yard,
   :build_pkg,
index 109083199e96e9790208e25fba2c7c58ea92f1b2..b75d78c58263798c6462d81ed8a1774a349d604b 100644 (file)
@@ -2,15 +2,14 @@
 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"]
 
@@ -20,8 +19,6 @@ Gpkg.gem_specification do |gpkg|
   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"
diff --git a/atv/bin/atv b/atv/bin/atv
new file mode 100755 (executable)
index 0000000..f7a63f2
--- /dev/null
@@ -0,0 +1,15 @@
+#!/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
diff --git a/atv/lib/atv/channel.rb b/atv/lib/atv/channel.rb
new file mode 100644 (file)
index 0000000..3c63716
--- /dev/null
@@ -0,0 +1,33 @@
+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
diff --git a/atv/lib/atv/database.rb b/atv/lib/atv/database.rb
new file mode 100644 (file)
index 0000000..7afdceb
--- /dev/null
@@ -0,0 +1,54 @@
+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
diff --git a/atv/lib/atv/player.rb b/atv/lib/atv/player.rb
new file mode 100644 (file)
index 0000000..1709e1a
--- /dev/null
@@ -0,0 +1,43 @@
+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
diff --git a/atv/lib/atv/server.rb b/atv/lib/atv/server.rb
new file mode 100644 (file)
index 0000000..e81b8a8
--- /dev/null
@@ -0,0 +1,24 @@
+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
diff --git a/atv/lib/database.rb b/atv/lib/database.rb
deleted file mode 100644 (file)
index 3b66f4d..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-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
diff --git a/atv/spec/database_spec.rb b/atv/spec/database_spec.rb
new file mode 100644 (file)
index 0000000..591b97e
--- /dev/null
@@ -0,0 +1,4 @@
+require "atv/database"
+
+describe ATV::Database do
+end
index f60708e2f84ace4195194e631a48b980e7e35b95..62e4cd3677e8a4f75fbaabda7f3ef198d308ef73 100644 (file)
@@ -11,5 +11,3 @@ SimpleCov.start do
     command_name "RSpec"
   end
 end
-
-require "gentex/gems/atv"