about summary refs log tree commit homepage
path: root/bin/dtas-tl
diff options
context:
space:
mode:
Diffstat (limited to 'bin/dtas-tl')
-rwxr-xr-xbin/dtas-tl93
1 files changed, 54 insertions, 39 deletions
diff --git a/bin/dtas-tl b/bin/dtas-tl
index 1ce18de..c7f4c83 100755
--- a/bin/dtas-tl
+++ b/bin/dtas-tl
@@ -1,5 +1,5 @@
 #!/usr/bin/env ruby
-# Copyright (C) 2013-2016 all contributors <dtas-all@nongnu.org>
+# Copyright (C) all contributors <dtas-all@nongnu.org>
 # License: GPL-3.0+ <https://www.gnu.org/licenses/gpl-3.0.txt>
 # frozen_string_literal: true
 # encoding: binary
@@ -7,6 +7,8 @@
 # itself is also unstable, but better than this one probably).
 require 'dtas/unix_client'
 require 'shellwords'
+$stdout.binmode
+$stderr.binmode
 
 def get_track_ids(c)
   track_ids = c.req("tl tracks")
@@ -16,14 +18,18 @@ def get_track_ids(c)
   track_ids
 end
 
-def fix_enc!(str, enc)
-  str.force_encoding(enc)
-  str.force_encoding(Encoding::ASCII_8BIT) unless str.valid_encoding?
+def each_track(c)
+  get_track_ids(c).each_slice(128) do |track_ids|
+    res = c.req("tl get #{track_ids.join(' ')}")
+    res = Shellwords.split(res.sub!(/\A\d+ /, ''))
+    while line = res.shift
+      yield line
+    end
+  end
 end
 
 def do_edit(c)
   require 'dtas/edit_client'
-  require 'yaml'
   require 'tempfile'
   extend DTAS::EditClient
   tmp = Tempfile.new(%w(dtas-tl-edit .txt))
@@ -31,19 +37,14 @@ def do_edit(c)
   tmp_path = tmp.path
   orig = []
   orig_idx = {}
-  enc = Encoding.default_external
 
-  get_track_ids(c).each_slice(128) do |track_ids|
-    res = c.req("tl get #{track_ids.join(' ')}")
-    res = Shellwords.split(res.sub!(/\A\d+ /, ''))
-    while line = res.shift
-      line.sub!(/\A(\d+)=/n, '') or abort "unexpected line=#{line.inspect}\n"
-      fix_enc!(line, enc)
-      track_id = $1.to_i
-      orig_idx[track_id] = orig.size
-      orig << track_id
-      tmp.write("#{Shellwords.escape(line)} =#{track_id}\n")
-    end
+  each_track(c) do |line|
+    line.sub!(/\A(\d+)=/n, '') or abort "unexpected line=#{line.inspect}\n"
+    track_id = $1.to_i
+    orig_idx[track_id] = orig.size
+    orig << track_id
+    line = Shellwords.escape(line) if line.include?("\n")
+    tmp.write("#{line} =#{track_id}\n")
   end
   tmp.flush
 
@@ -51,7 +52,7 @@ def do_edit(c)
   # jump to the line of the currently playing track if using vi or vim
   # Patches for other editors welcome: dtas-all@nongnu.org
   if ed =~ /vim?\z/
-    cur = YAML.load(c.req('current'))
+    cur = DTAS.yaml_load(c.req('current'))
     if tl = cur['tracklist']
       if pos = tl['pos']
         ed += " +#{pos + 1}"
@@ -100,14 +101,8 @@ def do_edit(c)
   non_existent = []
   add.each do |path, after_id|
     orig = path
-    path = Shellwords.split(path)[0]
-    path = File.expand_path(path)
-    unless File.exist?(path)
-      path = orig.dup
-      fix_enc!(path, enc)
-      path = Shellwords.split(path)[0]
-      path = File.expand_path(path)
-    end
+    path = File.expand_path(orig)
+    path = File.expand_path(Shellwords.split(path)[0]) unless File.exist?(path)
 
     if File.exist?(path)
       cmd = %W(tl add #{path})
@@ -140,15 +135,35 @@ end
 
 c = DTAS::UNIXClient.new
 case cmd = ARGV[0]
-when "cat"
-  enc = Encoding.default_external
-  get_track_ids(c).each_slice(128) do |track_ids|
-    res = c.req("tl get #{track_ids.join(' ')}")
-    res = Shellwords.split(res.sub!(/\A\d+ /, ''))
-    while line = res.shift
-      fix_enc!(line, enc)
-      print "#{line}\n"
+when 'cat'
+  each_track(c) { |line| print "#{line}\n" }
+when 'prune'
+  c2 = nil
+  pending = 0
+  each_track(c) do |line|
+    line.sub!(/\A(\d+)=/n, '') or abort "unexpected line=#{line.inspect}\n"
+    track_id = $1.to_i
+    ok = false
+    begin
+      st = File.stat(line)
+      ok = st.readable? && st.size?
+    rescue Errno::ENOENT, Errno::ENOTDIR, Errno::EACCES => e
+      warn "# #{line}: #{e.class}"
+      # raise other exceptions
     end
+    unless ok
+      c2 ||= DTAS::UNIXClient.new
+      if pending > 5
+        c2.res_wait
+        pending -= 1
+      end
+      pending += 1
+      c2.req_start("tl remove #{track_id}")
+    end
+  end
+  while pending > 0
+    c2.res_wait
+    pending -= 1
   end
 when 'aac' # add-after-current
   ARGV.shift
@@ -173,11 +188,11 @@ when "reto"
   re = ARGV[1]
   time = ARGV[2]
   re = Regexp.quote(re) if fixed
-  re = ignorecase ? %r{#{re}}i : %r{#{re}}
-  get_track_ids(c).each do |track_id|
-    res = c.req("tl get #{track_id}")
-    res.sub!(/\A1 \d+=/, '')
-    if re =~ res
+  re = ignorecase ? %r{#{re}}in : %r{#{re}}n
+  each_track(c) do |line|
+    line.sub!(/\A(\d+)=/n, '') or abort "unexpected line=#{line.inspect}\n"
+    track_id = $1
+    if re =~ line
       req = %W(tl goto #{track_id})
       req << time if time
       res = c.req(req)