listlace 0.0.8 → 0.0.9
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/Gemfile.lock +7 -4
- data/lib/listlace/commands/library_commands.rb +58 -0
- data/lib/listlace/library/database.rb +6 -10
- data/lib/listlace/library/selectors.rb +11 -0
- data/lib/listlace/library.rb +41 -7
- data/lib/listlace/models/track.rb +5 -0
- data/lib/listlace.rb +1 -0
- data/listlace.gemspec +4 -3
- metadata +36 -4
data/Gemfile.lock
CHANGED
@@ -1,13 +1,15 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
listlace (0.0.
|
4
|
+
listlace (0.0.9)
|
5
5
|
activerecord
|
6
6
|
activesupport
|
7
|
+
bundler
|
7
8
|
open4
|
8
9
|
plist
|
9
10
|
pry
|
10
11
|
sqlite3
|
12
|
+
taglib-ruby
|
11
13
|
|
12
14
|
GEM
|
13
15
|
remote: http://rubygems.org/
|
@@ -24,9 +26,9 @@ GEM
|
|
24
26
|
i18n (~> 0.6)
|
25
27
|
multi_json (~> 1.0)
|
26
28
|
arel (3.0.2)
|
27
|
-
builder (3.0.
|
29
|
+
builder (3.0.3)
|
28
30
|
coderay (1.0.7)
|
29
|
-
i18n (0.6.
|
31
|
+
i18n (0.6.1)
|
30
32
|
method_source (0.8)
|
31
33
|
multi_json (1.3.6)
|
32
34
|
open4 (1.3.0)
|
@@ -36,8 +38,9 @@ GEM
|
|
36
38
|
method_source (~> 0.8)
|
37
39
|
slop (~> 3.3.1)
|
38
40
|
rake (0.9.2.2)
|
39
|
-
slop (3.3.
|
41
|
+
slop (3.3.3)
|
40
42
|
sqlite3 (1.3.6)
|
43
|
+
taglib-ruby (0.5.1)
|
41
44
|
tzinfo (0.3.33)
|
42
45
|
|
43
46
|
PLATFORMS
|
@@ -9,6 +9,64 @@ module Listlace
|
|
9
9
|
library.save_playlist(playlist)
|
10
10
|
end
|
11
11
|
|
12
|
+
def like
|
13
|
+
if player.current_track.respond_to?(:rating)
|
14
|
+
player.current_track.increment! :rating
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def dislike
|
19
|
+
if player.current_track.respond_to?(:rating)
|
20
|
+
player.current_track.decrement! :rating
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def add(path, options = {})
|
25
|
+
if File.directory?(path)
|
26
|
+
extensions = {}
|
27
|
+
Array(options.delete(:extensions)).each do |ext|
|
28
|
+
extensions[ext.to_s] = true
|
29
|
+
end
|
30
|
+
|
31
|
+
num_tracks = 0
|
32
|
+
Dir[File.join(path, "**", "*")].each do |file|
|
33
|
+
unless File.directory?(file)
|
34
|
+
ext = File.extname(file).sub(/^\./, "")
|
35
|
+
if extensions[ext].nil?
|
36
|
+
print "Do you want to add files with the '.#{ext}' extension [y/N]? "
|
37
|
+
if gets[0].downcase == "y"
|
38
|
+
extensions[ext] = true
|
39
|
+
else
|
40
|
+
extensions[ext] = false
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
if extensions[ext]
|
45
|
+
if library.add_track(file, options)
|
46
|
+
num_tracks += 1
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
if num_tracks == 0
|
53
|
+
puts "Can't find any audio files there. Perhaps they are already added?"
|
54
|
+
elsif num_tracks == 1
|
55
|
+
puts "1 track added."
|
56
|
+
else
|
57
|
+
puts "#{num_tracks} tracks added."
|
58
|
+
end
|
59
|
+
else
|
60
|
+
if library.add_track(path, options)
|
61
|
+
puts "1 track added."
|
62
|
+
else
|
63
|
+
puts "Track couldn't be added. Perhaps it's not an audio file?"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
rescue Library::FileNotFoundError => e
|
67
|
+
puts e.message
|
68
|
+
end
|
69
|
+
|
12
70
|
# Imports the music library from another program. Currently only iTunes is
|
13
71
|
# supported.
|
14
72
|
def import(from, path)
|
@@ -47,27 +47,23 @@ module Listlace
|
|
47
47
|
t.string :album
|
48
48
|
t.string :album_artist
|
49
49
|
t.string :genre
|
50
|
-
t.string :kind
|
51
|
-
t.integer :size
|
52
50
|
t.integer :total_time
|
53
51
|
t.integer :disc_number
|
54
52
|
t.integer :disc_count
|
55
53
|
t.integer :track_number
|
56
54
|
t.integer :track_count
|
57
55
|
t.integer :year
|
58
|
-
t.datetime :date_modified
|
59
|
-
t.datetime :date_added
|
56
|
+
t.datetime :date_modified, null: false
|
57
|
+
t.datetime :date_added, null: false
|
60
58
|
t.integer :bit_rate
|
61
59
|
t.integer :sample_rate
|
62
60
|
t.text :comments
|
63
|
-
t.integer :play_count
|
61
|
+
t.integer :play_count, null: false, default: 0
|
64
62
|
t.datetime :play_date
|
65
|
-
t.integer :skip_count
|
63
|
+
t.integer :skip_count, null: false, default: 0
|
66
64
|
t.datetime :skip_date
|
67
|
-
t.integer :rating
|
68
|
-
t.
|
69
|
-
t.boolean :album_rating_computed
|
70
|
-
t.string :location
|
65
|
+
t.integer :rating, null: false, default: 0
|
66
|
+
t.string :location, null: false
|
71
67
|
end
|
72
68
|
|
73
69
|
create_table :playlists do |t|
|
@@ -20,6 +20,16 @@ module Listlace
|
|
20
20
|
end
|
21
21
|
end
|
22
22
|
|
23
|
+
# Selects all the tracks in the library.
|
24
|
+
def all
|
25
|
+
playlist library.tracks
|
26
|
+
end
|
27
|
+
|
28
|
+
# Selects no tracks, returning an empty playlist.
|
29
|
+
def none
|
30
|
+
playlist
|
31
|
+
end
|
32
|
+
|
23
33
|
# The length selector is an integer selector for the length of a track. A
|
24
34
|
# plain integer given to it represents the number of seconds. It can also take
|
25
35
|
# a String in the format "1:23", to represent 83 seconds, for example. These
|
@@ -149,6 +159,7 @@ module Listlace
|
|
149
159
|
# If given no arguments, it returns a blank playlist.
|
150
160
|
#
|
151
161
|
def playlist(*args)
|
162
|
+
args << [] if args.empty?
|
152
163
|
args.map do |object|
|
153
164
|
case object
|
154
165
|
when Track
|
data/lib/listlace/library.rb
CHANGED
@@ -55,6 +55,40 @@ module Listlace
|
|
55
55
|
playlist
|
56
56
|
end
|
57
57
|
|
58
|
+
def add_track(path, options = {})
|
59
|
+
metadata = options.dup
|
60
|
+
if File.exists?(path)
|
61
|
+
TagLib::FileRef.open(path) do |file|
|
62
|
+
if tag = file.tag
|
63
|
+
metadata[:album] ||= tag.album
|
64
|
+
metadata[:artist] ||= tag.artist
|
65
|
+
metadata[:comments] ||= tag.comment
|
66
|
+
metadata[:genre] ||= tag.genre
|
67
|
+
metadata[:title] ||= tag.title
|
68
|
+
metadata[:track_number] ||= tag.track unless tag.track.zero?
|
69
|
+
metadata[:year] ||= tag.year unless tag.year.zero?
|
70
|
+
end
|
71
|
+
|
72
|
+
if prop = file.audio_properties
|
73
|
+
metadata[:bit_rate] = prop.bitrate
|
74
|
+
metadata[:sample_rate] = prop.sample_rate
|
75
|
+
metadata[:total_time] = prop.length * 1000
|
76
|
+
end
|
77
|
+
|
78
|
+
if metadata[:title].nil? or metadata[:title].empty?
|
79
|
+
metadata[:title] = File.basename(path, ".*")
|
80
|
+
end
|
81
|
+
|
82
|
+
metadata[:location] = File.expand_path(path)
|
83
|
+
|
84
|
+
track = Track.new(metadata)
|
85
|
+
track.save && track
|
86
|
+
end
|
87
|
+
else
|
88
|
+
raise FileNotFoundError, "File '%s' doesn't exist." % [path]
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
58
92
|
def import(from, path, options = {})
|
59
93
|
logger = options[:logger]
|
60
94
|
if not File.exists?(path)
|
@@ -67,6 +101,11 @@ module Listlace
|
|
67
101
|
num_tracks = 0
|
68
102
|
whitelist = tracks.new.attributes.keys
|
69
103
|
data["Tracks"].each do |track_id, row|
|
104
|
+
if row["Kind"] !~ /audio/
|
105
|
+
logger.("[skipping non-audio file]") if logger
|
106
|
+
next
|
107
|
+
end
|
108
|
+
|
70
109
|
# row already contains a hash of attributes almost ready to be passed to
|
71
110
|
# ActiveRecord. We just need to modify the keys, e.g. change "Play Count"
|
72
111
|
# to "play_count".
|
@@ -91,13 +130,8 @@ module Listlace
|
|
91
130
|
end
|
92
131
|
|
93
132
|
track = tracks.new(attributes)
|
94
|
-
|
95
|
-
|
96
|
-
if track.save
|
97
|
-
num_tracks += 1
|
98
|
-
end
|
99
|
-
else
|
100
|
-
logger.("[skipping non-audio file]") if logger
|
133
|
+
if track.save
|
134
|
+
num_tracks += 1
|
101
135
|
end
|
102
136
|
end
|
103
137
|
logger.("Imported #{num_tracks} tracks successfully.") if logger
|
@@ -3,6 +3,11 @@ module Listlace
|
|
3
3
|
has_many :playlist_items
|
4
4
|
has_many :playlists, through: :playlist_items
|
5
5
|
|
6
|
+
validates :location, presence: true, uniqueness: true
|
7
|
+
|
8
|
+
before_create { |track| track.date_added = Time.now }
|
9
|
+
before_save { |track| track.date_modified = Time.now }
|
10
|
+
|
6
11
|
def increment_skip_count
|
7
12
|
increment! :skip_count
|
8
13
|
update_column :skip_date, Time.now
|
data/lib/listlace.rb
CHANGED
data/listlace.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "listlace"
|
3
|
-
s.version = "0.0.
|
4
|
-
s.date = "2012-09-
|
3
|
+
s.version = "0.0.9"
|
4
|
+
s.date = "2012-09-17"
|
5
5
|
s.summary = "A music player in a REPL."
|
6
6
|
s.description = "Listlace is a music player which is interacted with through a Ruby REPL."
|
7
7
|
s.author = "Jeremy Ruten"
|
@@ -10,13 +10,14 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.license = "MIT"
|
11
11
|
s.required_ruby_version = ">= 1.9.2"
|
12
12
|
s.requirements << "mplayer"
|
13
|
+
s.requirements << "taglib"
|
13
14
|
s.executables << "listlace"
|
14
15
|
|
15
16
|
s.files = ["Gemfile", "Gemfile.lock", "LICENSE", "listlace.gemspec", "README.md", "README.old"]
|
16
17
|
s.files += ["bin/listlace"]
|
17
18
|
s.files += Dir["lib/**/*.rb"]
|
18
19
|
|
19
|
-
%w(pry plist sqlite3 activerecord activesupport open4).each do |gem_name|
|
20
|
+
%w(bundler pry plist sqlite3 activerecord activesupport open4 taglib-ruby).each do |gem_name|
|
20
21
|
s.add_runtime_dependency gem_name
|
21
22
|
end
|
22
23
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: listlace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.9
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-09-
|
12
|
+
date: 2012-09-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: pry
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -107,6 +123,22 @@ dependencies:
|
|
107
123
|
- - ! '>='
|
108
124
|
- !ruby/object:Gem::Version
|
109
125
|
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: taglib-ruby
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :runtime
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
110
142
|
- !ruby/object:Gem::Dependency
|
111
143
|
name: rake
|
112
144
|
requirement: !ruby/object:Gem::Requirement
|
@@ -173,10 +205,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
173
205
|
version: '0'
|
174
206
|
requirements:
|
175
207
|
- mplayer
|
208
|
+
- taglib
|
176
209
|
rubyforge_project:
|
177
|
-
rubygems_version: 1.8.
|
210
|
+
rubygems_version: 1.8.23
|
178
211
|
signing_key:
|
179
212
|
specification_version: 3
|
180
213
|
summary: A music player in a REPL.
|
181
214
|
test_files: []
|
182
|
-
has_rdoc:
|