listlace 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,52 +0,0 @@
1
- module Listlace
2
- # The queue command. Simply appends tracks to the queue. It creates a playlist
3
- # with the arguments you give it, so anything you can pass to the playlist()
4
- # method you can pass to this. It returns the queue, so you can use this
5
- # method as an accessor by not passing any arguments.
6
- def q(*args)
7
- $player.queue playlist(*args)
8
- $player.queue
9
- end
10
-
11
- # Clears the queue.
12
- def clear
13
- $player.clear
14
- puts "Queue cleared."
15
- end
16
-
17
- # Shuffles the queue, keeping the current track at the top.
18
- def shuffle
19
- $player.shuffle
20
- puts "Shuffled."
21
- end
22
-
23
- # Sorts the queue by a list of fields and directions in the form of a symbol,
24
- # or uses the proc given to it, which should take two Tracks and return -1, 0,
25
- # or 1.
26
- def sort(by = :artist_asc_album_asc_track_number_asc, &proc)
27
- if proc
28
- $player.sort(&proc)
29
- else
30
- $player.sort do |a, b|
31
- result = 0
32
- by.to_s.scan(/([a-z_]+?)_(asc|desc)(?:_|$)/).each do |column, direction|
33
- a_value = a.send(column)
34
- b_value = b.send(column)
35
- a_value = a_value.downcase if a_value.respond_to? :downcase
36
- b_value = b_value.downcase if b_value.respond_to? :downcase
37
- dir = (direction == "desc") ? -1 : 1
38
- if a_value != b_value
39
- if a_value.nil? || b_value.nil?
40
- result = dir
41
- else
42
- result = (a_value <=> b_value) * dir
43
- end
44
- break
45
- end
46
- end
47
- result
48
- end
49
- end
50
- puts "Sorted."
51
- end
52
- end
@@ -1,186 +0,0 @@
1
- module Listlace
2
- STRING_SELECTORS = %w(name artist composer album album_artist genre comments location)
3
- INTEGER_SELECTORS = %w(disc_number disc_count track_number track_count year bit_rate sample_rate play_count skip_count rating)
4
-
5
- STRING_SELECTORS.each do |column|
6
- define_method(column) do |*args|
7
- options = args.last.is_a?(Hash) ? args.pop : {}
8
-
9
- playlists = args.map { |query| string_selector(column, query, options) }
10
- playlist *playlists
11
- end
12
- end
13
-
14
- INTEGER_SELECTORS.each do |column|
15
- define_method(column) do |*args|
16
- playlists = args.map { |arg| integer_selector(column, arg) }
17
- playlist *playlists
18
- end
19
- end
20
-
21
- # rename the "name" selector to "song"
22
- alias_method :song, :name
23
- remove_method :name
24
-
25
- # The length selector is an integer selector for the length of a track. A
26
- # plain integer given to it represents the number of seconds. It can also take
27
- # a String in the format "1:23", to represent 83 seconds, for example. These
28
- # can be part of a Range, as usual: "1:23".."2:05", for example.
29
- def length(*args)
30
- normalize = lambda do |value|
31
- case value
32
- when String
33
- Track.parse_time(value)
34
- when Integer
35
- value * 1000
36
- when Range
37
- (normalize.(value.begin))..(normalize.(value.end))
38
- end
39
- end
40
-
41
- playlists = args.map do |arg|
42
- if arg.is_a? Hash
43
- key = arg.keys.first
44
- arg[key] = normalize.(arg[key])
45
- else
46
- arg = normalize.(arg)
47
- end
48
-
49
- # If they want tracks of length "0:05", for example, we need to look for
50
- # tracks that are from 5000 to 5999 milliseconds long.
51
- if arg.is_a? Integer
52
- arg = (arg)..(arg + 999)
53
- end
54
-
55
- integer_selector(:total_time, arg)
56
- end
57
-
58
- playlist *playlists
59
- end
60
-
61
- # Makes a playlist out of tracks that match the string query on the given
62
- # column. It's SQL underneath, so you can use % and _ as wildcards in the
63
- # query. By default, % wildcards are inserted on the left and right of your
64
- # query. Use the :match option to change this:
65
- #
66
- # :match => :middle "%query%" (default)
67
- # :match => :left "query%"
68
- # :match => :right "%query"
69
- # :match => :exact "query"
70
- #
71
- # This method shouldn't have to be used directly. Many convenient methods are
72
- # generated for you, one for each string field you may want to select on.
73
- # These are: artist, composer, album, album_artist, genre, comments, location.
74
- # For example:
75
- #
76
- # artist :muse, match: :exact #=> playlist (108 tracks)
77
- # composer :rachmanino #=> playlist (33 tracks)
78
- #
79
- # To match the name of a track, use song:
80
- #
81
- # song "frontier psychiatrist" #=> playlist (1 track)
82
- #
83
- def string_selector(column, query, options = {})
84
- options[:match] ||= :middle
85
-
86
- query = {
87
- exact: "#{query}",
88
- left: "#{query}%",
89
- right: "%#{query}",
90
- middle: "%#{query}%"
91
- }[options[:match]]
92
-
93
- tracks = Track.arel_table
94
- PlaylistArray.new(Track.where(tracks[column].matches(query)).all)
95
- end
96
-
97
- # Makes a playlist out of tracks that satisfy certain conditions on the given
98
- # integer column. You can pass an exact value to check for equality, a range,
99
- # or a hash that specifies greater-than and less-than options like this:
100
- #
101
- # integer_selector :year, greater_than: 2000 #=> playlist (3555 tracks)
102
- #
103
- # The possible operators, with their shortcuts, are:
104
- #
105
- # :greater_than / :gt
106
- # :less_than / :lt
107
- # :greater_than_or_equal / :gte
108
- # :less_than_or_equal / :lte
109
- # :not_equal / :ne
110
- #
111
- # Note: You can only use one of these operators at a time. If you want a
112
- # range, use a Range.
113
- #
114
- # This method shouldn't have to be used directly. Many convenient methods are
115
- # generated for you, one for each integer field you may want to select on.
116
- # These are: disc_number, disc_count, track_number, track_count, year,
117
- # bit_rate, sample_rate, play_count, skip_count, rating, length. Length is
118
- # special, it can take any of the time formats that the seek command can. For
119
- # example:
120
- #
121
- # year 2010..2012 #=> playlist (1060 tracks)
122
- # length gt: "4:00" #=> playlist (2543 tracks)
123
- #
124
- def integer_selector(column, value_or_options)
125
- if value_or_options.is_a? Hash
126
- operator = {
127
- greater_than: ">",
128
- gt: ">",
129
- less_than: "<",
130
- lt: "<",
131
- greater_than_or_equal: ">=",
132
- gte: ">=",
133
- less_than_or_equal: "<=",
134
- lte: "<=",
135
- not_equal: "<>",
136
- ne: "<>"
137
- }[value_or_options.keys.first]
138
- tracks = Track.where("tracks.#{column} #{operator} ?", value_or_options.values.first)
139
- PlaylistArray.new(tracks.all)
140
- else
141
- tracks = Track.arel_table
142
- PlaylistArray.new(Track.where(column => value_or_options).all)
143
- end
144
- end
145
-
146
- # Creates or looks up a playlist. You can pass any number of multiple types of
147
- # objects to make a playlist:
148
- #
149
- # Track: Makes a playlist with one track
150
- # ActiveRecord::Relation: Makes a playlist out of the resulting Track or Playlist records
151
- # Symbol or String: Tries to retrieve a saved playlist with the given name.
152
- # If it can't find one, it creates a new one.
153
- #
154
- # You can also pass in the results of a selector. In this way you can create a
155
- # playlist out of many smaller pieces.
156
- #
157
- # If given no arguments, it returns a blank playlist.
158
- #
159
- def playlist(*args)
160
- args.map do |object|
161
- case object
162
- when Track
163
- PlaylistArray.new([object])
164
- when Playlist
165
- PlaylistArray.new([object.tracks.all], object.name)
166
- when PlaylistArray
167
- object
168
- when Array
169
- playlist *object
170
- when ActiveRecord::Relation
171
- if object.table.name == "tracks"
172
- PlaylistArray.new([object.all])
173
- elsif object.table.name == "playlists"
174
- playlist *object.all
175
- end
176
- when Symbol, String
177
- playlists = Playlist.arel_table
178
- if playlist = Playlist.where(playlists[:name].matches(object.to_s)).first
179
- PlaylistArray.new(playlist)
180
- else
181
- PlaylistArray.new([], object)
182
- end
183
- end
184
- end.inject(:+)
185
- end
186
- end
File without changes
@@ -1,74 +0,0 @@
1
- module Listlace
2
- module Database
3
- extend self
4
-
5
- ADAPTER = "sqlite3"
6
- PATH = "#{Listlace::DIR}/library.sqlite3"
7
-
8
- def connect
9
- ActiveRecord::Base.establish_connection(adapter: ADAPTER, database: PATH)
10
- end
11
-
12
- def exists?
13
- File.exists? PATH
14
- end
15
-
16
- def delete
17
- FileUtils.rm PATH
18
- end
19
-
20
- def wipe
21
- delete
22
- connect
23
- generate_schema
24
- end
25
-
26
- def generate_schema
27
- ActiveRecord::Schema.define do
28
- create_table :tracks do |t|
29
- t.integer :original_id
30
- t.string :name
31
- t.string :artist
32
- t.string :composer
33
- t.string :album
34
- t.string :album_artist
35
- t.string :genre
36
- t.string :kind
37
- t.integer :size
38
- t.integer :total_time
39
- t.integer :disc_number
40
- t.integer :disc_count
41
- t.integer :track_number
42
- t.integer :track_count
43
- t.integer :year
44
- t.datetime :date_modified
45
- t.datetime :date_added
46
- t.integer :bit_rate
47
- t.integer :sample_rate
48
- t.text :comments
49
- t.integer :play_count
50
- t.integer :play_date
51
- t.datetime :play_date_utc
52
- t.integer :skip_count
53
- t.datetime :skip_date
54
- t.integer :rating
55
- t.integer :album_rating
56
- t.boolean :album_rating_computed
57
- t.string :location
58
- end
59
-
60
- create_table :playlists do |t|
61
- t.string :name
62
- t.datetime :created_at
63
- t.datetime :updated_at
64
- end
65
-
66
- create_table :playlist_items do |t|
67
- t.references :playlist, null: false
68
- t.references :track, null: false
69
- t.integer :position
70
- end
71
- end
72
- end
73
- end
74
- end
@@ -1,51 +0,0 @@
1
- module Listlace
2
- # This is a simple MPlayer wrapper, it just handles opening the MPlayer
3
- # process, hooking into when mplayer exits (when the song is done), and
4
- # issuing commands through the slave protocol.
5
- class MPlayer
6
- def initialize(track, &on_quit)
7
- cmd = "/usr/bin/mplayer -slave -quiet #{Shellwords.shellescape(track.location)}"
8
- @pid, @stdin, @stdout, @stderr = Open4.popen4(cmd)
9
- @paused = false
10
- @extra_lines = 0
11
-
12
- until @stdout.gets["playback"]
13
- end
14
-
15
- @quit_hook_active = false
16
- @quit_hook = Thread.new do
17
- Process.wait(@pid)
18
- @quit_hook_active = true
19
- on_quit.call
20
- end
21
- end
22
-
23
- def command(cmd, options = {})
24
- if cmd == "pause"
25
- @paused = !@paused
26
- elsif @paused
27
- cmd = "pausing #{cmd}"
28
- end
29
-
30
- @stdin.puts cmd
31
-
32
- if options[:expect_answer]
33
- answer = "\n"
34
- answer = @stdout.gets.sub("\e[A\r\e[K", "") while answer == "\n"
35
- answer
36
- end
37
- end
38
-
39
- def quit
40
- @quit_hook.kill unless @quit_hook_active
41
- command "quit" if alive?
42
- end
43
-
44
- def alive?
45
- Process.getpgid(@pid)
46
- true
47
- rescue Errno::ESRCH
48
- false
49
- end
50
- end
51
- end
@@ -1,82 +0,0 @@
1
- module Listlace
2
- class PlaylistArray < Array
3
- attr_accessor :name, :model
4
-
5
- def initialize(tracks_or_playlist = [], name = :playlist)
6
- if tracks_or_playlist.is_a? Playlist
7
- replace tracks_or_playlist.tracks.to_a
8
- @name = tracks_or_playlist.name
9
- @model = tracks_or_playlist
10
- else
11
- replace tracks_or_playlist.to_a
12
- @name = name.to_s
13
- @model = nil
14
- end
15
- end
16
-
17
- def save(name = nil)
18
- if @model
19
- @model.playlist_items.destroy_all
20
- @model.name = @name = name if name
21
- else
22
- @name = name if name
23
- @model = Playlist.new(name: @name)
24
- end
25
-
26
- if @model.save
27
- each.with_index do |track, i|
28
- item = PlaylistItem.new(position: i)
29
- item.playlist = @model
30
- item.track = track
31
- item.save!
32
- end
33
- @model
34
- else
35
- false
36
- end
37
- end
38
-
39
- def <<(other)
40
- if other.is_a? Track
41
- super
42
- else
43
- other.each do |track|
44
- self << track
45
- end
46
- end
47
- end
48
-
49
- def +(other)
50
- result = self.dup
51
- result << Listlace.playlist(other)
52
- result
53
- end
54
-
55
- def &(other)
56
- replace super
57
- end
58
-
59
- def shuffle_except(track)
60
- ary = dup
61
- dup.shuffle_except! track
62
- dup
63
- end
64
-
65
- def shuffle_except!(track)
66
- replace([track] + (self - [track]).shuffle)
67
- end
68
-
69
- def to_s
70
- "%s (%d track%s)" % [@name || "playlist", length, ("s" if length != 1)]
71
- end
72
-
73
- def inspect
74
- to_s
75
- end
76
-
77
- # override pry
78
- def pretty_inspect
79
- inspect
80
- end
81
- end
82
- end