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: 
         |