segue 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/lib/segue.rb ADDED
@@ -0,0 +1,135 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "curses"
4
+ require "rainbow"
5
+ require_relative "segue/version"
6
+ require_relative "segue/paths"
7
+ require_relative "segue/player"
8
+ require_relative "segue/player_controller"
9
+ require_relative "segue/preferences"
10
+ require_relative "segue/queue"
11
+ require_relative "segue/notifiers"
12
+ require_relative "segue/scrobbler"
13
+
14
+ module Segue
15
+ COLOURS = [0, 2, 5, 6, 8, 9, 11].freeze
16
+ KEYS = { " " => :pause, "n" => :skip, "p" => :play, "s" => :stop }.freeze
17
+
18
+ def self.autoplay(value)
19
+ Segue::Preferences.new[:autoplay] = value == "on"
20
+ end
21
+
22
+ def self.clear
23
+ Segue::Queue.clear
24
+ end
25
+
26
+ def self.crossfade(value)
27
+ Segue::Preferences.new[:crossfade] = value == "on"
28
+ end
29
+
30
+ def self.history
31
+ path = Segue::Paths.history
32
+ return unless File.exist?(path)
33
+
34
+ puts File.read(path)
35
+ end
36
+
37
+ def self.list
38
+ started = Segue::Preferences.new[:started]
39
+ offset = 0
40
+ Segue::Queue.to_enum(:each).each_with_index do |track, index|
41
+ puts list_line(track, index, started && Time.at(started + offset))
42
+ offset += track[:length].to_i
43
+ end
44
+ end
45
+
46
+ def self.list_line(track, index, start_time)
47
+ parts = [Rainbow(index.to_s).magenta]
48
+ parts << start_time.strftime("%I:%M:%S") if start_time
49
+ parts += [Rainbow(track[:title]).green, "by", Rainbow(track[:artist]).yellow]
50
+ parts += ["from", Rainbow(track[:album]).cyan] unless (track[:album] || "").empty?
51
+ parts << "(#{track[:length] / 60} minutes and #{track[:length] % 60} seconds)" if track[:length]
52
+ parts.join(" ")
53
+ end
54
+
55
+ def self.pause
56
+ Segue::Preferences.new[:pause] = true
57
+ end
58
+
59
+ def self.play
60
+ Segue::Preferences.new[:play] = true
61
+ end
62
+
63
+ def self.player
64
+ # Start the controller before taking over the screen so that a failure to
65
+ # launch mpv is readable rather than swallowed by curses
66
+ player_controller = Segue::PlayerController.new
67
+ window = open_window
68
+
69
+ loop do
70
+ render(window, player_controller.next)
71
+
72
+ key = window.getch.to_s
73
+ break if key == "q"
74
+
75
+ send(KEYS[key]) if KEYS.key?(key)
76
+ sleep 0.2
77
+ end
78
+ ensure
79
+ player_controller&.cleanup
80
+ Curses.close_screen
81
+ end
82
+
83
+ def self.open_window
84
+ Curses.init_screen
85
+ Curses.start_color
86
+ Curses.curs_set(0)
87
+ Curses.noecho
88
+ COLOURS.each { |colour| Curses.init_pair(colour, colour, 0) }
89
+ Curses::Window.new(0, 0, 1, 2).tap { |window| window.nodelay = true }
90
+ end
91
+
92
+ def self.render(window, lines)
93
+ window.setpos(0, 0)
94
+ lines.each do |colour, text|
95
+ window.attron(Curses.color_pair(colour)) { window << text }
96
+ Curses.clrtoeol
97
+ end
98
+ (window.maxy - window.cury).times { window.deleteln }
99
+ window.refresh
100
+ end
101
+
102
+ def self.remove(index)
103
+ Segue::Queue.remove(index) { list }
104
+ end
105
+
106
+ def self.queue(paths)
107
+ paths.each do |path|
108
+ if File.file?(path)
109
+ Segue::Queue.add(path)
110
+ else
111
+ Dir.glob("#{path}/**/*.*").each { |child_path| Segue::Queue.add(child_path) }
112
+ end
113
+ end
114
+ end
115
+
116
+ def self.scrobble(value)
117
+ preferences = Segue::Preferences.new
118
+ preferences[:scrobble] = value == "on"
119
+ scrobbler = Segue::Scrobbler.load if preferences.scrobble?
120
+ preferences[:scrobble] = false unless scrobbler
121
+ end
122
+
123
+ def self.skip
124
+ Segue::Preferences.new[:skip] = true
125
+ end
126
+
127
+ def self.stop
128
+ Segue::Preferences.new[:stop] = true
129
+ end
130
+
131
+ def self.swap(args)
132
+ a, b = *args
133
+ Segue::Queue.swap(a, b) { list }
134
+ end
135
+ end
metadata ADDED
@@ -0,0 +1,105 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: segue
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Mark Ryall
8
+ bindir: exe
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: curses
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - ">="
17
+ - !ruby/object:Gem::Version
18
+ version: '0'
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - ">="
24
+ - !ruby/object:Gem::Version
25
+ version: '0'
26
+ - !ruby/object:Gem::Dependency
27
+ name: rainbow
28
+ requirement: !ruby/object:Gem::Requirement
29
+ requirements:
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ - !ruby/object:Gem::Dependency
41
+ name: rexml
42
+ requirement: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ type: :runtime
48
+ prerelease: false
49
+ version_requirements: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ email:
55
+ - mark@ryall.name
56
+ executables:
57
+ - segue
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - ".rspec"
62
+ - ".rubocop.yml"
63
+ - ".tool-versions"
64
+ - Gemfile
65
+ - LICENSE.txt
66
+ - README.md
67
+ - Rakefile
68
+ - bin/console
69
+ - bin/setup
70
+ - exe/segue
71
+ - lib/segue.rb
72
+ - lib/segue/ffmpeg.rb
73
+ - lib/segue/mpv.rb
74
+ - lib/segue/notifiers.rb
75
+ - lib/segue/paths.rb
76
+ - lib/segue/player.rb
77
+ - lib/segue/player_controller.rb
78
+ - lib/segue/preferences.rb
79
+ - lib/segue/queue.rb
80
+ - lib/segue/scrobbler.rb
81
+ - lib/segue/settings.rb
82
+ - lib/segue/version.rb
83
+ homepage: https://github.com/markryall/segue
84
+ licenses:
85
+ - MIT
86
+ metadata:
87
+ rubygems_mfa_required: 'true'
88
+ rdoc_options: []
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: 3.2.0
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ requirements: []
102
+ rubygems_version: 4.0.16
103
+ specification_version: 4
104
+ summary: Crossfading queue daemon for mpv
105
+ test_files: []