itc 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +24 -0
- data/Gemfile +3 -0
- data/LICENSE +22 -0
- data/README.md +74 -0
- data/Rakefile +2 -0
- data/bin/itc +54 -0
- data/extra/completion/zsh/_itc +53 -0
- data/itc.gemspec +26 -0
- data/lib/itc.rb +8 -0
- data/lib/itc/command.rb +49 -0
- data/lib/itc/database.rb +83 -0
- data/lib/itc/musiclib.rb +46 -0
- data/lib/itc/player.rb +60 -0
- data/lib/itc/version.rb +3 -0
- metadata +115 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bbb1fbc96993d0b0cb77574b931c1ea62d2dbee8
|
4
|
+
data.tar.gz: 5d5b693c549eb9e7e01ca6364ce6fc09569dd3a7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: db27c20f1615babc9460ea5c33ee0412384190382b244fb58c6cc405bfc0766b27605c86311bbb82dee18d578db94af81cd34e0fe52099390aad0d726fa12cf7
|
7
|
+
data.tar.gz: 561aec5e3943d49608fd9ff6933c37a7c26da316f2f798b0a2a6ada4082bf877ee94d44425109d3ed86cecdeec9e46e427b2dfffb00a0782e735006b3f4feede
|
data/.gitignore
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
23
|
+
*.swp
|
24
|
+
.DS_Store
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014, Ragnar B. Johannsson
|
2
|
+
All rights reserved.
|
3
|
+
|
4
|
+
Redistribution and use in source and binary forms, with or without
|
5
|
+
modification, are permitted provided that the following conditions are met:
|
6
|
+
|
7
|
+
1. Redistributions of source code must retain the above copyright notice, this
|
8
|
+
list of conditions and the following disclaimer.
|
9
|
+
2. Redistributions in binary form must reproduce the above copyright notice,
|
10
|
+
this list of conditions and the following disclaimer in the documentation
|
11
|
+
and/or other materials provided with the distribution.
|
12
|
+
|
13
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
14
|
+
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
15
|
+
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
16
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
17
|
+
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
18
|
+
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
19
|
+
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
20
|
+
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
21
|
+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
22
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
data/README.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
## Itc
|
2
|
+
|
3
|
+
Itc is an iTunes command line client. It indexes iTunes' Music Library XML file into a SQLite3 database for faster lookup and provides shell tab completion for metadata.
|
4
|
+
|
5
|
+
|
6
|
+
### Installation
|
7
|
+
|
8
|
+
Install the gem:
|
9
|
+
|
10
|
+
$ gem install itc
|
11
|
+
|
12
|
+
Copy the tab completion definitions under `extra/completion/` to the appropriate paths for your system and shell.
|
13
|
+
|
14
|
+
|
15
|
+
### Usage
|
16
|
+
|
17
|
+
After installing, start by indexing the iTunes Music Library:
|
18
|
+
|
19
|
+
$ itc index
|
20
|
+
|
21
|
+
This generates a SQLite3 database in `$HOME/.itc.db` which will act as a cache for the iTunes Music Library XML files. Rerun the index command after adding new content to iTunes. Alternatively, add it to crontab to keep things in sync.
|
22
|
+
|
23
|
+
After indexing you can start querying the library:
|
24
|
+
|
25
|
+
$ itc list artist
|
26
|
+
|
27
|
+
will return a list of all artists in the library.
|
28
|
+
|
29
|
+
$ itc play artist=Daft\ Punk
|
30
|
+
|
31
|
+
will start to play all songs and albums by Daft Punk in the Library.
|
32
|
+
|
33
|
+
$ itc play artist=Ibrahim\ Maalouf album=Wind
|
34
|
+
|
35
|
+
will play the album Wind by Ibrahim Maalouf. Notice that if the tab completions are installed there is no need to laboriously spell out full names for the filters as they will tab complete just fine.
|
36
|
+
|
37
|
+
Recognized filters for the **list** and **play** commands are `artist`, `album`, `song`, `year` and `genre`.
|
38
|
+
|
39
|
+
Following are all recognized commands:
|
40
|
+
|
41
|
+
* **index** - (Re)index the music database
|
42
|
+
* **list** - Search for tracks
|
43
|
+
* **next** - Skip to next song
|
44
|
+
* **pause** - Pause playing
|
45
|
+
* **play** - Commence playing
|
46
|
+
* **previous** - Go back one song
|
47
|
+
* **status** - Show playing status, playlist position
|
48
|
+
|
49
|
+
To gauge the position within the current album or playlist use the **status** command:
|
50
|
+
|
51
|
+
$ itc play artist=Emika album=DVA
|
52
|
+
$ itc next
|
53
|
+
$ itc status
|
54
|
+
Emika - DVA - Hush (Interlude) feat. Michaela Srumova
|
55
|
+
▶ Emika - DVA - Young Minds
|
56
|
+
Emika - DVA - She Beats
|
57
|
+
Emika - DVA - Filters
|
58
|
+
Emika - DVA - After The Fall
|
59
|
+
Emika - DVA - Sing To Me
|
60
|
+
Emika - DVA - Dem Worlds
|
61
|
+
Emika - DVA - Primary Colours
|
62
|
+
Emika - DVA - Sleep With My Enemies
|
63
|
+
Emika - DVA - Wicked Game
|
64
|
+
Emika - DVA - Fight For Your Love
|
65
|
+
Emika - DVA - Mouth To Mouth
|
66
|
+
Emika - DVA - Searching
|
67
|
+
Emika - DVA - Centuries
|
68
|
+
Emika - DVA - Criminal Gift
|
69
|
+
$
|
70
|
+
|
71
|
+
|
72
|
+
### License
|
73
|
+
|
74
|
+
BSD 2-Clause. See the LICENSE file for details.
|
data/Rakefile
ADDED
data/bin/itc
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'itc'
|
4
|
+
|
5
|
+
def usage(msg="")
|
6
|
+
puts "Error: #{msg}\n\n" unless msg == ""
|
7
|
+
|
8
|
+
puts <<-USAGE.gsub(/^ /, "")
|
9
|
+
Usage: itc <command> [filters...]
|
10
|
+
|
11
|
+
Commands:
|
12
|
+
help - This message
|
13
|
+
index - (Re)index the music database
|
14
|
+
list - Search for tracks
|
15
|
+
next - Next song
|
16
|
+
pause - Pause playing
|
17
|
+
play - Play
|
18
|
+
previous - Previous song
|
19
|
+
status - Playing status, playlist position
|
20
|
+
|
21
|
+
Filters (valid with play and list commands):
|
22
|
+
artist - Artist name
|
23
|
+
album - Album name
|
24
|
+
song - Song name
|
25
|
+
year - Release yeaar
|
26
|
+
genre - Genre name
|
27
|
+
|
28
|
+
USAGE
|
29
|
+
|
30
|
+
exit msg == "" ? 0 : 1
|
31
|
+
end
|
32
|
+
|
33
|
+
usage "No command specified" if ARGV.size() < 1
|
34
|
+
|
35
|
+
begin
|
36
|
+
cmd = ARGV.shift
|
37
|
+
filters = {}
|
38
|
+
|
39
|
+
usage if cmd == "help"
|
40
|
+
|
41
|
+
while action = ARGV.shift do
|
42
|
+
sp = action.split("=", 2)
|
43
|
+
filters[sp[0]] = sp.size() == 1 ? "" : sp[1]
|
44
|
+
end
|
45
|
+
|
46
|
+
Command.execute cmd, filters
|
47
|
+
rescue InvalidFilterNumberException => e
|
48
|
+
usage e.message
|
49
|
+
rescue UnknownFilterException => e
|
50
|
+
usage "Unknown filter #{e.message}"
|
51
|
+
rescue UnknownCommandException
|
52
|
+
usage "Unknown command #{cmd}"
|
53
|
+
end
|
54
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
#compdef itc
|
2
|
+
|
3
|
+
local context state state_descr line expl list_item
|
4
|
+
local -a commands
|
5
|
+
local -A opt_args
|
6
|
+
|
7
|
+
function _itc_list {
|
8
|
+
local i filters=""
|
9
|
+
for i in {2..$#line}; do
|
10
|
+
if [[ ! $line[$i] == $list_item* ]]; then
|
11
|
+
filters="${filters}$line[$i] "
|
12
|
+
fi
|
13
|
+
done
|
14
|
+
|
15
|
+
local cmd item IFS=$'\n'
|
16
|
+
cmd="itc list $filters $list_item"
|
17
|
+
for item in $(eval ${cmd}); do
|
18
|
+
compadd $expl[@] -- $item
|
19
|
+
done
|
20
|
+
|
21
|
+
return 0
|
22
|
+
}
|
23
|
+
|
24
|
+
_arguments '1:command:->cmds' '*:filter:->filters' && ret=0
|
25
|
+
|
26
|
+
case "$state" in
|
27
|
+
(cmds)
|
28
|
+
commands=(
|
29
|
+
'list:Search for tracks' \
|
30
|
+
'status:Show playing status, playlist position' \
|
31
|
+
'play:Play' \
|
32
|
+
'index:(Re)index the music database' \
|
33
|
+
'next:Next song' \
|
34
|
+
'previous:Previous song' \
|
35
|
+
'pause:Pause playing')
|
36
|
+
_describe 'values' commands
|
37
|
+
;;
|
38
|
+
(filters)
|
39
|
+
case "$line[1]" in
|
40
|
+
(play)
|
41
|
+
;&
|
42
|
+
(list)
|
43
|
+
_values -w 'option' \
|
44
|
+
'artist[Artist name]:artist:{list_item=artist _itc_list}' \
|
45
|
+
'album[Album name]:album:{list_item=album _itc_list}' \
|
46
|
+
'song[Song name]:song:{list_item=song _itc_list}' \
|
47
|
+
'genre[Genre name]:genre:{list_item=genre _itc_list}' \
|
48
|
+
'year[Release year]:year:{list_item=year _itc_list}'
|
49
|
+
;;
|
50
|
+
esac
|
51
|
+
;;
|
52
|
+
esac
|
53
|
+
|
data/itc.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'itc/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "itc"
|
8
|
+
spec.version = Itc::VERSION
|
9
|
+
spec.authors = ["Ragnar B. Johannsson"]
|
10
|
+
spec.email = ["ragnar@igo.is"]
|
11
|
+
spec.summary = %q{iTunes CLI}
|
12
|
+
spec.description = %q{iTunes CLI with tab completions}
|
13
|
+
spec.homepage = "https://github.com/ragnar-johannsson/itc"
|
14
|
+
spec.license = "BSD"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "sqlite3", "~> 1.3"
|
22
|
+
spec.add_runtime_dependency "htmlentities", "~> 4.3"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
end
|
data/lib/itc.rb
ADDED
data/lib/itc/command.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
class Command
|
4
|
+
def self.execute(action, filters)
|
5
|
+
db = Database.new
|
6
|
+
player = Player.new
|
7
|
+
xml = ENV["HOME"] + "/Music/iTunes/iTunes Music Library.xml"
|
8
|
+
|
9
|
+
supported_filters = ("artist" "album" "song" "genre" "year")
|
10
|
+
filters.keys.each do |filter|
|
11
|
+
raise UnknownFilterException, filter unless supported_filters.include? filter
|
12
|
+
end
|
13
|
+
|
14
|
+
case action
|
15
|
+
when "index"
|
16
|
+
db.reindex MusicLibrary.new(xml)
|
17
|
+
when "list"
|
18
|
+
raise InvalidFilterNumberException, "No filter specified" if filters.empty?
|
19
|
+
puts db.list(filters).collect { |f| f.last }
|
20
|
+
when "play"
|
21
|
+
player.play filters.empty? ? {} : db.list_ids(filters)
|
22
|
+
when "pause"
|
23
|
+
player.pause
|
24
|
+
when "next"
|
25
|
+
player.next
|
26
|
+
when "previous", "prev"
|
27
|
+
player.previous
|
28
|
+
when "status"
|
29
|
+
if player.state == "stopped"
|
30
|
+
puts "iTunes is #{player.state}\n"
|
31
|
+
return
|
32
|
+
end
|
33
|
+
|
34
|
+
curr_song = player.current_track
|
35
|
+
state_icon = player.state == "playing" ? "▶" : "‖"
|
36
|
+
playlist = player.current_playlist_tracks.split(", ")
|
37
|
+
db.list_by_ids(playlist.size < 1000 ? playlist : [curr_song]).collect do |track|
|
38
|
+
printf " %s %s - %s - %s\n", track[0].to_s == curr_song ? state_icon : " ",
|
39
|
+
track[1], track[2], track[3]
|
40
|
+
end
|
41
|
+
else
|
42
|
+
raise UnknownCommandException
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class InvalidFilterNumberException < StandardError; end
|
48
|
+
class UnknownFilterException < StandardError; end
|
49
|
+
class UnknownCommandException < StandardError; end
|
data/lib/itc/database.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'sqlite3'
|
4
|
+
|
5
|
+
class Database
|
6
|
+
def initialize
|
7
|
+
@db = SQLite3::Database.new(ENV["HOME"] + "/.itc.db")
|
8
|
+
end
|
9
|
+
|
10
|
+
def reset
|
11
|
+
@db.execute_batch <<-SQL
|
12
|
+
drop index if exists tracks_artist_index;
|
13
|
+
drop index if exists tracks_album_index;
|
14
|
+
drop index if exists tracks_song_index;
|
15
|
+
drop index if exists tracks_genre_index;
|
16
|
+
drop index if exists tracks_year_index;
|
17
|
+
drop table if exists tracks;
|
18
|
+
|
19
|
+
create table tracks (
|
20
|
+
track_id INTEGER PRIMARY KEY,
|
21
|
+
artist VARCHAR DEFAULT NULL,
|
22
|
+
album VARCHAR DEFAULT NULL,
|
23
|
+
song VARCHAR DEFAULT NULL,
|
24
|
+
genre VARCHAR DEFAULT NULL,
|
25
|
+
year VARCHAR DEFAULT NULL,
|
26
|
+
disc_number INTEGER DEFAULT NULL,
|
27
|
+
track_number INTEGER DEFAULT NULL
|
28
|
+
);
|
29
|
+
|
30
|
+
create index tracks_artist_index on tracks (artist);
|
31
|
+
create index tracks_album_index on tracks (album);
|
32
|
+
create index tracks_song_index on tracks (song);
|
33
|
+
create index tracks_genre_index on tracks (genre);
|
34
|
+
create index tracks_year_index on tracks (year);
|
35
|
+
SQL
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_tracks(tracks)
|
39
|
+
@db.transaction do |db|
|
40
|
+
db.prepare("insert into tracks values (?, ?, ?, ?, ?, ?, ?, ?)") do |stmt|
|
41
|
+
tracks.each do |t|
|
42
|
+
stmt.execute t[:track_id].to_i, t[:artist], t[:album], t[:name],
|
43
|
+
t[:genre], t[:year], t[:disc_number].to_i, t[:track_number].to_i
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def reindex(music)
|
50
|
+
reset
|
51
|
+
add_tracks music.tracks
|
52
|
+
end
|
53
|
+
|
54
|
+
def list(filters)
|
55
|
+
c = filters.keys.collect { |k| "#{k} like \"%#{filters[k]}%\"" }
|
56
|
+
condition = c.empty? ? "" : "where #{c.join(' and ')}"
|
57
|
+
fields = filters.keys.join(",")
|
58
|
+
@db.execute <<-SQL
|
59
|
+
select distinct #{fields} from tracks #{condition} order by artist, album, disc_number, track_number
|
60
|
+
SQL
|
61
|
+
end
|
62
|
+
|
63
|
+
def list_ids(filters)
|
64
|
+
c = filters.keys.collect { |k| "#{k} like \"%#{filters[k]}%\"" }
|
65
|
+
condition = c.empty? ? "" : "where #{c.join(' and ')}"
|
66
|
+
@db.execute <<-SQL
|
67
|
+
select track_id from tracks #{condition} order by artist, album, disc_number, track_number
|
68
|
+
SQL
|
69
|
+
end
|
70
|
+
|
71
|
+
def list_by_ids(ids)
|
72
|
+
c = ids.collect { |i| "track_id = #{i}" }
|
73
|
+
condition = c.empty? ? "" : "where #{c.join(' or ')}"
|
74
|
+
@db.execute <<-SQL
|
75
|
+
select
|
76
|
+
track_id, artist, album, song
|
77
|
+
from
|
78
|
+
tracks #{condition}
|
79
|
+
order by
|
80
|
+
artist, album, disc_number, track_number
|
81
|
+
SQL
|
82
|
+
end
|
83
|
+
end
|
data/lib/itc/musiclib.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require 'htmlentities'
|
4
|
+
|
5
|
+
class MusicLibrary
|
6
|
+
attr_accessor :file, :tracks
|
7
|
+
|
8
|
+
def initialize(file)
|
9
|
+
@file = file
|
10
|
+
@tracks = []
|
11
|
+
|
12
|
+
parse_xml
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse_xml
|
16
|
+
entities = HTMLEntities.new
|
17
|
+
in_tracks = false
|
18
|
+
track = {}
|
19
|
+
|
20
|
+
IO.foreach(File.expand_path(@file)) do |line|
|
21
|
+
line = line.force_encoding("UTF-8")
|
22
|
+
|
23
|
+
if line =~ /^\t<key>Tracks<\/key>$/
|
24
|
+
in_tracks = true
|
25
|
+
next
|
26
|
+
end
|
27
|
+
|
28
|
+
if in_tracks then
|
29
|
+
if line =~ /^\t\t\t<key>(.*)<\/key><(date|integer|string)>(.*)<\/.*>$/
|
30
|
+
key = $1.downcase.split.join("_").intern
|
31
|
+
track[key] = entities.decode($3.to_s)
|
32
|
+
next
|
33
|
+
elsif line =~ /^\t\t<\/dict>$/ then
|
34
|
+
@tracks.push(track.dup)
|
35
|
+
track.clear
|
36
|
+
next
|
37
|
+
elsif in_tracks && line =~ /^\t<\/dict>$/
|
38
|
+
in_tracks = false
|
39
|
+
next
|
40
|
+
else
|
41
|
+
next
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
data/lib/itc/player.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
class Player
|
4
|
+
def execute(script)
|
5
|
+
`osascript -e '#{script}'`.gsub(/\n$/, "")
|
6
|
+
end
|
7
|
+
|
8
|
+
def play(tracks)
|
9
|
+
if tracks.empty?
|
10
|
+
execute 'tell application "iTunes" to play'
|
11
|
+
else
|
12
|
+
tracks = tracks.collect {|track| "database ID is #{track}"}
|
13
|
+
execute <<-SCRIPT
|
14
|
+
set pName to "itc"
|
15
|
+
tell application "iTunes"
|
16
|
+
if not ((name of playlists) contains pName) then
|
17
|
+
set itcPlaylist to make new playlist with properties {name:pName}
|
18
|
+
else
|
19
|
+
set itcPlaylist to playlist pName
|
20
|
+
delete every track of itcPlaylist
|
21
|
+
end if
|
22
|
+
|
23
|
+
duplicate (every track whose #{
|
24
|
+
tracks.join(" or ")
|
25
|
+
}) to itcPlaylist
|
26
|
+
|
27
|
+
play itcPlaylist
|
28
|
+
end tell
|
29
|
+
SCRIPT
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def pause
|
34
|
+
execute 'tell application "iTunes" to pause'
|
35
|
+
end
|
36
|
+
|
37
|
+
def next
|
38
|
+
execute 'tell application "iTunes" to next track'
|
39
|
+
end
|
40
|
+
|
41
|
+
def previous
|
42
|
+
execute 'tell application "iTunes" to previous track'
|
43
|
+
end
|
44
|
+
|
45
|
+
def state
|
46
|
+
execute 'tell application "iTunes" to return player state'
|
47
|
+
end
|
48
|
+
|
49
|
+
def current_track
|
50
|
+
execute 'tell application "iTunes" to return database ID of current track'
|
51
|
+
end
|
52
|
+
|
53
|
+
def current_playlist_tracks
|
54
|
+
execute <<-SCRIPT
|
55
|
+
tell application "iTunes"
|
56
|
+
return database ID of tracks of current playlist
|
57
|
+
end tell
|
58
|
+
SCRIPT
|
59
|
+
end
|
60
|
+
end
|
data/lib/itc/version.rb
ADDED
metadata
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: itc
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ragnar B. Johannsson
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-05-30 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: sqlite3
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: htmlentities
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.6'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: iTunes CLI with tab completions
|
70
|
+
email:
|
71
|
+
- ragnar@igo.is
|
72
|
+
executables:
|
73
|
+
- itc
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- ".gitignore"
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- bin/itc
|
83
|
+
- extra/completion/zsh/_itc
|
84
|
+
- itc.gemspec
|
85
|
+
- lib/itc.rb
|
86
|
+
- lib/itc/command.rb
|
87
|
+
- lib/itc/database.rb
|
88
|
+
- lib/itc/musiclib.rb
|
89
|
+
- lib/itc/player.rb
|
90
|
+
- lib/itc/version.rb
|
91
|
+
homepage: https://github.com/ragnar-johannsson/itc
|
92
|
+
licenses:
|
93
|
+
- BSD
|
94
|
+
metadata: {}
|
95
|
+
post_install_message:
|
96
|
+
rdoc_options: []
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 2.2.2
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: iTunes CLI
|
115
|
+
test_files: []
|