traktor-nml 0.2.0 → 0.3.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.
- checksums.yaml +4 -4
- data/README.md +81 -30
- data/lib/traktor/nml.rb +9 -9
- data/lib/traktor/nml/collection.rb +32 -6
- data/lib/traktor/nml/cue.rb +20 -0
- data/lib/traktor/nml/file.rb +18 -0
- data/lib/traktor/nml/playlist.rb +19 -0
- data/lib/traktor/nml/track.rb +30 -0
- data/lib/traktor/nml/version.rb +1 -1
- data/spec/traktor/nml_spec.rb +37 -3
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a975f0344949062aa901da4cfb09178e10877377
|
4
|
+
data.tar.gz: 325b02f803405a3a7dc7015a0b5f4c79cd09d1bd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 213163283d378e4d088ff1ce248323590e50c0c9de164bcc723b9b66f2477ac97023a9b032069a8aa203bd14cc57e4f6589a8c57124c0965dd28adfb354b6f50
|
7
|
+
data.tar.gz: a18161acdadb9157f9e89a1bfde78c6ec1c16f2b987f425aa2643347b375bfe7cc96ebe8f14a43042fd414dee4d994dc5d9c05042c4fb6cc8a4966e756eddd43
|
data/README.md
CHANGED
@@ -27,44 +27,95 @@ Or install it yourself as:
|
|
27
27
|
require 'traktor/nml'
|
28
28
|
|
29
29
|
Traktor::NML.parse File.open("path/to/playlist.nml")
|
30
|
+
Traktor::NML.load "path/to/playlist.nml"
|
30
31
|
# or
|
31
32
|
Traktor::NML.parse content_of_nml
|
32
33
|
```
|
33
34
|
|
34
35
|
`Traktor::NML.parse` will return array of hash like this:
|
35
36
|
|
36
|
-
```
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
:
|
65
|
-
|
37
|
+
```irb
|
38
|
+
irb(main):001:0> require 'traktor/nml'
|
39
|
+
=> true
|
40
|
+
irb(main):002:0> Traktor::NML.parse(File.read(File.expand_path "./spec/traktor/traktor-nml-demo.nml"))
|
41
|
+
=> #<Traktor::NML::Playlist:0x007f8f3bbdd270 @tracks=[
|
42
|
+
#<Traktor::NML::Track:0x007f8f3bbfc058
|
43
|
+
@title="Green Night Parade (PandaBoY Remix)",
|
44
|
+
@artist="fu_mou",
|
45
|
+
@album={:title=>"Green Night Parade EP", :track=>"6"},
|
46
|
+
@primarykey="G:/:Music/:fu_mou/:Green Night Parade EP/:06 Green Night Parade (PandaBoY Remi.mp3",
|
47
|
+
@genre="ALTEMA Records",
|
48
|
+
@label="",
|
49
|
+
@release_date="2011/1/1",
|
50
|
+
@playtime=371.0,
|
51
|
+
@bpm=131.999,
|
52
|
+
@key="3d",
|
53
|
+
@musical_key="2",
|
54
|
+
@cues=[
|
55
|
+
#<Traktor::NML::Cue:0x007f8f3bbfeb28 @name="n.n.", @type=0, @start=483.713, @length=0.0, @repeats=-1, @hotcue=0>,
|
56
|
+
#<Traktor::NML::Cue:0x007f8f3bbfe538 @name="n.n.", @type=4, @start=4119.93, @length=0.0, @repeats=-1, @hotcue=1>,
|
57
|
+
#<Traktor::NML::Cue:0x007f8f3bbfdf48 @name="n.n.", @type=0, @start=33211.1, @length=0.0, @repeats=-1, @hotcue=2>,
|
58
|
+
#<Traktor::NML::Cue:0x007f8f3bbfd958 @name="n.n.", @type=0, @start=47756.6, @length=0.0, @repeats=-1, @hotcue=3>,
|
59
|
+
#<Traktor::NML::Cue:0x007f8f3bbfd340 @name="n.n.", @type=0, @start=76847.6, @length=0.0, @repeats=-1, @hotcue=4>,
|
60
|
+
#<Traktor::NML::Cue:0x007f8f3bbfcd00 @name="n.n.", @type=0, @start=91393.2, @length=0.0, @repeats=-1, @hotcue=5>,
|
61
|
+
#<Traktor::NML::Cue:0x007f8f3bbfc6c0 @name="n.n.", @type=0, @start=120484.0,@length=0.0, @repeats=-1, @hotcue=6>,
|
62
|
+
#<Traktor::NML::Cue:0x007f8f3bbfc0a8 @name="n.n.", @type=0, @start=149576.0, @length=0.0, @repeats=-1, @hotcue=7>
|
63
|
+
]
|
64
|
+
>,
|
65
|
+
#<Traktor::NML::Track:0x007f8f3bc14dd8
|
66
|
+
@title="Sweet Tear(Y calla K Cut Electro Remix)",
|
67
|
+
@artist="Calla Soiled",
|
68
|
+
@album={:title=>"Sweet Tear EP", :track=>"2"},
|
69
|
+
@primarykey="G:/:Music/:Calla Soiled/:Sweet Tear EP/:02 Sweet Tear(Y calla K Cut Electro.mp3",
|
70
|
+
@genre="ALTEMA Records",
|
71
|
+
@label="",
|
72
|
+
@release_date="2010/1/1",
|
73
|
+
@playtime=320.0,
|
74
|
+
@bpm=132.0,
|
75
|
+
@key="12d",
|
76
|
+
@musical_key="5",
|
77
|
+
@cues=[
|
78
|
+
#<Traktor::NML::Cue:0x007f8f3bc74b48 @name="n.n.", @type=0, @start=26.5843, @length=0.0, @repeats=-1, @hotcue=0>,
|
79
|
+
#<Traktor::NML::Cue:0x007f8f3bc74558 @name="n.n.", @type=4, @start=3666.41, @length=0.0, @repeats=-1, @hotcue=1>,
|
80
|
+
#<Traktor::NML::Cue:0x007f8f3bc17e98 @name="n.n.", @type=0, @start=18208.4, @length=0.0, @repeats=-1, @hotcue=2>,
|
81
|
+
#<Traktor::NML::Cue:0x007f8f3bc17330 @name="n.n.", @type=0, @start=32753.9, @length=0.0, @repeats=-1, @hotcue=3>,
|
82
|
+
#<Traktor::NML::Cue:0x007f8f3bc167c8 @name="n.n.", @type=0, @start=47299.3, @length=0.0, @repeats=-1, @hotcue=4>,
|
83
|
+
#<Traktor::NML::Cue:0x007f8f3bc15cb0 @name="n.n.", @type=0, @start=90935.7, @length=0.0, @repeats=-1, @hotcue=5>,
|
84
|
+
#<Traktor::NML::Cue:0x007f8f3bc15468 @name="n.n.", @type=0, @start=120027.0, @length=0.0, @repeats=-1, @hotcue=6>,
|
85
|
+
#<Traktor::NML::Cue:0x007f8f3bc14e28 @name="n.n.", @type=0, @start=149117.0, @length=0.0, @repeats=-1, @hotcue=7>
|
86
|
+
]
|
87
|
+
>,
|
88
|
+
#<Traktor::NML::Track:0x007f8f3bbde620
|
89
|
+
@title="もしも星屑が泣いたとして",
|
90
|
+
@artist="Calla Soiled",
|
91
|
+
@album={:title=>"Dirty Nucleus", :track=>"7"},
|
92
|
+
@primarykey="G:/:Music/:Calla Soiled/:Dirty Nucleus/:07 もしも星屑が泣いたとして.mp3",
|
93
|
+
@genre="",
|
94
|
+
@label="",
|
95
|
+
@release_date="2010/1/1",
|
96
|
+
@playtime=362.0,
|
97
|
+
@bpm=139.005,
|
98
|
+
@key="11m",
|
99
|
+
@musical_key="19",
|
100
|
+
@cues=[
|
101
|
+
#<Traktor::NML::Cue:0x007f8f3bbe5948 @name="Beat Marker", @type=4, @start=434.042, @length=0.0, @repeats=-1, @hotcue=-1>,
|
102
|
+
#<Traktor::NML::Cue:0x007f8f3bbe52e0 @name="n.n.", @type=4, @start=434.042, @length=0.0, @repeats=-1, @hotcue=0>,
|
103
|
+
#<Traktor::NML::Cue:0x007f8f3bbe4bd8 @name="n.n.", @type=0, @start=14246.2, @length=0.0, @repeats=-1, @hotcue=1>,
|
104
|
+
#<Traktor::NML::Cue:0x007f8f3bbe4520 @name="n.n.", @type=0, @start=28058.7, @length=0.0, @repeats=-1, @hotcue=2>,
|
105
|
+
#<Traktor::NML::Cue:0x007f8f3bbdfe80 @name="n.n.", @type=0, @start=41871.4, @length=0.0, @repeats=-1, @hotcue=3>,
|
106
|
+
#<Traktor::NML::Cue:0x007f8f3bbdf840 @name="n.n.", @type=0, @start=55683.6, @length=0.0, @repeats=-1, @hotcue=4>,
|
107
|
+
#<Traktor::NML::Cue:0x007f8f3bbdf250 @name="n.n.", @type=0, @start=83308.5, @length=0.0, @repeats=-1, @hotcue=5>,
|
108
|
+
#<Traktor::NML::Cue:0x007f8f3bbdec60 @name="n.n.", @type=0, @start=97121.0, @length=0.0, @repeats=-1, @hotcue=6>,
|
109
|
+
#<Traktor::NML::Cue:0x007f8f3bbde670 @name="n.n.", @type=0, @start=124746.0,@length=0.0, @repeats=-1, @hotcue=7>
|
110
|
+
]
|
111
|
+
>
|
112
|
+
]>
|
66
113
|
```
|
67
114
|
|
115
|
+
## Notice
|
116
|
+
|
117
|
+
* Release date may be like `YYYY/1/1` when only YEAR is specified in file
|
118
|
+
|
68
119
|
## Contributing
|
69
120
|
|
70
121
|
1. Fork it ( https://github.com/polamjag/traktor-nml/fork )
|
data/lib/traktor/nml.rb
CHANGED
@@ -1,15 +1,15 @@
|
|
1
|
-
require "traktor/nml/
|
2
|
-
require "traktor/nml/playlist"
|
3
|
-
require "traktor/nml/version"
|
4
|
-
require "oga"
|
1
|
+
require "traktor/nml/file"
|
5
2
|
|
6
3
|
module Traktor
|
7
4
|
module NML
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
5
|
+
class << self
|
6
|
+
def parse(content)
|
7
|
+
Traktor::NML::File.new(content).playlist
|
8
|
+
end
|
9
|
+
|
10
|
+
def load(filepath)
|
11
|
+
Traktor::NML::File.new(::File.read filepath).playlist
|
12
|
+
end
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -1,13 +1,18 @@
|
|
1
1
|
require "oga"
|
2
|
+
require "date"
|
3
|
+
require "traktor/nml/track"
|
4
|
+
require "traktor/nml/cue"
|
2
5
|
|
3
6
|
module Traktor
|
4
7
|
module NML
|
5
8
|
class Collection
|
9
|
+
include Enumerable
|
10
|
+
|
6
11
|
attr_reader :collection
|
7
12
|
|
8
13
|
def initialize(node)
|
9
14
|
@collection = node.map do |el|
|
10
|
-
{
|
15
|
+
Traktor::NML::Track.new({
|
11
16
|
title: try_text(el.attribute('TITLE')),
|
12
17
|
artist: try_text(el.attribute('ARTIST')),
|
13
18
|
album: {
|
@@ -20,30 +25,47 @@ module Traktor
|
|
20
25
|
genre: el.xpath('INFO[@GENRE]').attribute('GENRE').map{ |e| e.text }.join(", "),
|
21
26
|
label: el.xpath('INFO[@LABEL]').attribute('LABEL').map{ |e| e.text }.join(", "),
|
22
27
|
playtime: el.xpath('INFO[@PLAYTIME]').attribute('PLAYTIME').map{ |e| e.text.to_f }.first,
|
23
|
-
release_date: el.xpath('INFO[@RELEASE_DATE]').attribute('RELEASE_DATE').map{ |e| e.text }.join(", "),
|
28
|
+
release_date: parse_date(el.xpath('INFO[@RELEASE_DATE]').attribute('RELEASE_DATE').map{ |e| e.text }.join(", ")),
|
24
29
|
bpm: el.xpath('TEMPO[@BPM]').attribute('BPM').map{ |e| e.text.to_f }.first,
|
25
30
|
key: try_text(el.xpath('INFO[@KEY]').attribute('KEY').first),
|
26
31
|
musical_key: try_text(el.xpath('MUSICAL_KEY[@VALUE]').attribute('VALUE').first),
|
27
32
|
cues: el.xpath('CUE_V2').map do |cue|
|
28
|
-
{
|
33
|
+
Traktor::NML::Cue.new({
|
29
34
|
name: cue.attribute('NAME').value,
|
30
35
|
type: cue.attribute('TYPE').value.to_i,
|
31
36
|
start: cue.attribute('START').value.to_f,
|
32
37
|
length: cue.attribute('LEN').value.to_f,
|
33
38
|
repeats: cue.attribute('REPEATS').value.to_i,
|
34
39
|
hotcue: cue.attribute('HOTCUE').value.to_i
|
35
|
-
}
|
40
|
+
})
|
36
41
|
end
|
37
|
-
}
|
42
|
+
})
|
38
43
|
end
|
39
44
|
end
|
40
45
|
|
41
46
|
def track_from_primarykey(primarykey)
|
42
47
|
@collection.select do |track|
|
43
|
-
track
|
48
|
+
track.primarykey == primarykey
|
44
49
|
end.first
|
45
50
|
end
|
46
51
|
|
52
|
+
def length
|
53
|
+
@collection.length
|
54
|
+
end
|
55
|
+
alias_method :size, :length
|
56
|
+
|
57
|
+
def each
|
58
|
+
@collection.each do |track|
|
59
|
+
yield track
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def [](i)
|
64
|
+
@collection[i]
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
private
|
47
69
|
def try_text(elm)
|
48
70
|
if elm.nil?
|
49
71
|
""
|
@@ -51,6 +73,10 @@ module Traktor
|
|
51
73
|
elm.text
|
52
74
|
end
|
53
75
|
end
|
76
|
+
|
77
|
+
def parse_date(date)
|
78
|
+
Date.parse date unless date.empty?
|
79
|
+
end
|
54
80
|
end
|
55
81
|
end
|
56
82
|
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Traktor
|
2
|
+
module NML
|
3
|
+
class Cue
|
4
|
+
attr_reader :name, :type, :start, :length, :repeats, :hotcue
|
5
|
+
|
6
|
+
def initialize(info)
|
7
|
+
@name = info[:name]
|
8
|
+
@type = info[:type]
|
9
|
+
@start = info[:start]
|
10
|
+
@length = info[:length]
|
11
|
+
@repeats = info[:repeats]
|
12
|
+
@hotcue = info[:hotcue]
|
13
|
+
end
|
14
|
+
|
15
|
+
def [](key)
|
16
|
+
return self.instance_variable_get("@#{key.to_s}")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require "oga"
|
2
|
+
require "traktor/nml/collection"
|
3
|
+
require "traktor/nml/playlist"
|
4
|
+
|
5
|
+
module Traktor
|
6
|
+
module NML
|
7
|
+
class File
|
8
|
+
attr_reader :collection, :playlist
|
9
|
+
|
10
|
+
def initialize(content)
|
11
|
+
doc = Oga.parse_xml content
|
12
|
+
|
13
|
+
@collection = Traktor::NML::Collection.new doc.xpath('NML/COLLECTION/ENTRY')
|
14
|
+
@playlist = Traktor::NML::Playlist.new doc.xpath('NML/PLAYLISTS'), @collection
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/lib/traktor/nml/playlist.rb
CHANGED
@@ -3,13 +3,32 @@ require "oga"
|
|
3
3
|
module Traktor
|
4
4
|
module NML
|
5
5
|
class Playlist
|
6
|
+
include Enumerable
|
7
|
+
|
6
8
|
attr_reader :tracks
|
9
|
+
|
7
10
|
def initialize(node, collection)
|
8
11
|
@tracks = (find_playlist node).first.xpath('PLAYLIST/ENTRY/PRIMARYKEY').map do |track|
|
9
12
|
collection.track_from_primarykey track.attribute('KEY').text
|
10
13
|
end.compact
|
11
14
|
end
|
12
15
|
|
16
|
+
def length
|
17
|
+
@tracks.length
|
18
|
+
end
|
19
|
+
alias_method :size, :length
|
20
|
+
|
21
|
+
def each
|
22
|
+
@tracks.each do |track|
|
23
|
+
yield track
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def [](i)
|
28
|
+
@tracks[i]
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
13
32
|
def find_playlist(node)
|
14
33
|
node.each do |nd|
|
15
34
|
nd.xpath('NODE/SUBNODES').each do |elm|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Traktor
|
2
|
+
module NML
|
3
|
+
class Track
|
4
|
+
attr_reader :title, :artist, :album,
|
5
|
+
:primarykey,
|
6
|
+
:genre, :label, :release_date,
|
7
|
+
:playtime, :bpm, :key, :musical_key,
|
8
|
+
:cues
|
9
|
+
|
10
|
+
def initialize(info)
|
11
|
+
@title = info[:title]
|
12
|
+
@artist = info[:artist]
|
13
|
+
@album = info[:album]
|
14
|
+
@primarykey = info[:primarykey]
|
15
|
+
@genre = info[:genre]
|
16
|
+
@label = info[:label]
|
17
|
+
@release_date = info[:release_date]
|
18
|
+
@playtime = info[:playtime]
|
19
|
+
@bpm = info[:bpm]
|
20
|
+
@key = info[:key]
|
21
|
+
@musical_key = info[:musical_key]
|
22
|
+
@cues = info[:cues]
|
23
|
+
end
|
24
|
+
|
25
|
+
def [](key)
|
26
|
+
return self.instance_variable_get("@#{key.to_s}")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
data/lib/traktor/nml/version.rb
CHANGED
data/spec/traktor/nml_spec.rb
CHANGED
@@ -1,17 +1,51 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Traktor::NML do
|
4
|
+
before do
|
5
|
+
@path_nml_win = (File.join File.dirname(__FILE__), "win.nml")
|
6
|
+
@path_nml_win_embedded = (File.join File.dirname(__FILE__), "win_in_folder.nml")
|
7
|
+
@path_nml_osx = (File.join File.dirname(__FILE__), "osx.nml")
|
8
|
+
end
|
9
|
+
|
4
10
|
it 'has a version number' do
|
5
11
|
expect(Traktor::NML::VERSION).not_to be nil
|
6
12
|
end
|
7
13
|
|
8
14
|
it 'can parse nml file ver 18' do
|
9
|
-
expect((Traktor::NML.parse File.open
|
15
|
+
expect((Traktor::NML.parse File.open @path_nml_win).length).to eq(40)
|
10
16
|
end
|
11
17
|
it 'can parse nml file ver 18, playlist is in directory' do
|
12
|
-
expect((Traktor::NML.parse File.open
|
18
|
+
expect((Traktor::NML.parse File.open @path_nml_win_embedded).length).to eq(43)
|
13
19
|
end
|
14
20
|
it 'can parse nml file of OSX, ver 16' do
|
15
|
-
expect((Traktor::NML.parse File.open
|
21
|
+
expect((Traktor::NML.parse File.open @path_nml_osx).length).to eq(34)
|
22
|
+
end
|
23
|
+
|
24
|
+
describe Traktor::NML::Playlist do
|
25
|
+
before do
|
26
|
+
@playlist = Traktor::NML.load @path_nml_win
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'has length' do
|
30
|
+
expect(@playlist.length).to eq 40
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'is Enumerable' do
|
34
|
+
expect(@playlist.map{|pl| pl.title }.length).to eq 40
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe Traktor::NML::Collection do
|
39
|
+
before do
|
40
|
+
@file = Traktor::NML::File.new ::File.read @path_nml_win
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'has length' do
|
44
|
+
expect(@file.collection.length).to eq 40
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'is Enumerable' do
|
48
|
+
expect(@file.collection.map{|pl| pl.title }.length).to eq 40
|
49
|
+
end
|
16
50
|
end
|
17
51
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: traktor-nml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- polamjag
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oga
|
@@ -97,7 +97,10 @@ files:
|
|
97
97
|
- circle.yml
|
98
98
|
- lib/traktor/nml.rb
|
99
99
|
- lib/traktor/nml/collection.rb
|
100
|
+
- lib/traktor/nml/cue.rb
|
101
|
+
- lib/traktor/nml/file.rb
|
100
102
|
- lib/traktor/nml/playlist.rb
|
103
|
+
- lib/traktor/nml/track.rb
|
101
104
|
- lib/traktor/nml/version.rb
|
102
105
|
- spec/spec_helper.rb
|
103
106
|
- spec/traktor/nml_spec.rb
|