dmap-ng 0.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,88 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+ require 'dmap'
3
+
4
+ # Time to add your specs!
5
+ # http://rspec.info/
6
+ describe DMAP do
7
+ describe ".build" do
8
+ it "builds correctly" do
9
+ server_info = DMAP.build do
10
+ msrv do
11
+ mstt 200 # Status
12
+ mpro(0,2,0,6) # DMAP protocol version
13
+ apro(0,3,0,8) # DAAP protocol version
14
+ aeSV(0,3,0,1) # iTunes sharing version
15
+ aeFP true # ??
16
+ ated 3 # ??, 3 in euphony
17
+ msed false # ??, true in euphony
18
+ msml do # Magic fucking numbers.
19
+ msma 224677167504896 # euphony has 71359108752128
20
+ msma 219298093276928 # euphony has 1102738509824
21
+ msma 183156896570880 #euphony has 8799319904256
22
+ end
23
+ ceWM 'sup' # Welcome message
24
+ ceVO true # Voting?
25
+ minm "chendo\342\200\231s Library" # Server name
26
+ mslr true # ??
27
+ mstm 1800 # Timeout
28
+ msal true # ??
29
+ msas 3 # ??
30
+ msup true # ??
31
+ mspi true # ??
32
+ msex true # ??
33
+ msbr true # ??
34
+ msqy true # ??
35
+ msix true # ??
36
+ msrs true # ??
37
+ msdc 1 # Database count?
38
+
39
+ mstc Time.at(1271418369) # Current time
40
+ msto 36000 # UTC Offset
41
+ end
42
+ end
43
+
44
+ server_info.to_dmap.should == "msrv\000\000\001<mstt\000\000\000\004\000\000\000\310mpro\000\000\000\004\000\002\000\006apro\000\000\000\004\000\003\000\baeSV\000\000\000\004\000\003\000\001aeFP\000\000\000\001\001ated\000\000\000\002\000\003msed\000\000\000\001\000msml\000\000\0000msma\000\000\000\b\000\000\314W\272\302\036\000msma\000\000\000\b\000\000\307sP\363\037\000msma\000\000\000\b\000\000\246\224\211\302\036\000ceWM\000\000\000\003supceVO\000\000\000\001\001minm\000\000\000\022chendo\342\200\231s Librarymslr\000\000\000\001\001mstm\000\000\000\004\000\000\a\bmsal\000\000\000\001\001msas\000\000\000\001\003msup\000\000\000\001\001mspi\000\000\000\001\001msex\000\000\000\001\001msbr\000\000\000\001\001msqy\000\000\000\001\001msix\000\000\000\001\001msrs\000\000\000\001\001msdc\000\000\000\004\000\000\000\001mstc\000\000\000\004K\310N\001msto\000\000\000\004\000\000\214\240"
45
+ end
46
+ end
47
+
48
+ describe ".parse" do
49
+ it "parses server info data" do
50
+ expected = DMAP.build do
51
+ msrv do
52
+ mstt 200 # Status
53
+ mpro(0,2,0,6) # DMAP protocol version
54
+ apro(0,3,0,8) # DAAP protocol version
55
+ aeSV(0,3,0,1) # iTunes sharing version
56
+ aeFP true # ??
57
+ ated 3 # ??, 3 in euphony
58
+ msed false # ??, true in euphony
59
+ msml do # Magic fucking numbers.
60
+ msma 224677167504896 # euphony has 71359108752128
61
+ msma 219298093276928 # euphony has 1102738509824
62
+ msma 183156896570880 #euphony has 8799319904256
63
+ end
64
+ ceWM 'sup' # Welcome message
65
+ ceVO true # Voting?
66
+ minm "chendo\342\200\231s Library" # Server name
67
+ mslr true # ??
68
+ mstm 1800 # Timeout
69
+ msal true # ??
70
+ msas 3 # ??
71
+ msup true # ??
72
+ mspi true # ??
73
+ msex true # ??
74
+ msbr true # ??
75
+ msqy true # ??
76
+ msix true # ??
77
+ msrs true # ??
78
+ msdc 1 # Database count?
79
+
80
+ mstc Time.at(1271418369) # Current time
81
+ msto 36000 # UTC Offset
82
+ end
83
+ end
84
+
85
+ expected.should == DMAP.parse("msrv\000\000\001<mstt\000\000\000\004\000\000\000\310mpro\000\000\000\004\000\002\000\006apro\000\000\000\004\000\003\000\baeSV\000\000\000\004\000\003\000\001aeFP\000\000\000\001\001ated\000\000\000\002\000\003msed\000\000\000\001\000msml\000\000\0000msma\000\000\000\b\000\000\314W\272\302\036\000msma\000\000\000\b\000\000\307sP\363\037\000msma\000\000\000\b\000\000\246\224\211\302\036\000ceWM\000\000\000\003supceVO\000\000\000\001\001minm\000\000\000\022chendo\342\200\231s Librarymslr\000\000\000\001\001mstm\000\000\000\004\000\000\a\bmsal\000\000\000\001\001msas\000\000\000\001\003msup\000\000\000\001\001mspi\000\000\000\001\001msex\000\000\000\001\001msbr\000\000\000\001\001msqy\000\000\000\001\001msix\000\000\000\001\001msrs\000\000\000\001\001msdc\000\000\000\004\000\000\000\001mstc\000\000\000\004K\310N\001msto\000\000\000\004\000\000\214\240")
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,137 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "DSLs" do
4
+ describe "#to_dsl" do
5
+ it "returns a DSL string" do
6
+ DMAP.build do
7
+ cmgt do
8
+ mstt 200 # Status
9
+ cmvo 88 # Volume
10
+ end
11
+ end.to_dsl.should == <<-STR.gsub(/^ /, '').strip
12
+ cmgt do # unknown.list
13
+ mstt 200 # dmap.status
14
+ cmvo 88 # dmcp.volume
15
+ end
16
+ STR
17
+ end
18
+ end
19
+
20
+ describe ".build" do
21
+ it "must be able to handle empty list tags" do
22
+ lambda {
23
+ DMAP.build do
24
+ mlcl do
25
+ end
26
+ end
27
+ }.should_not raise_error
28
+ end
29
+
30
+ it "should throw an exception on unknown tags" do
31
+ lambda {
32
+ DMAP.build do
33
+ derp do
34
+ hurr "durr"
35
+ end
36
+ end
37
+ }.should raise_error
38
+ end
39
+
40
+ it "works with Array#each" do
41
+ DMAP.build do
42
+ apso do
43
+ mlcl do
44
+ %w(foo bar).each do |name|
45
+ mlit do
46
+ cann name
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end.should == DMAP.build do
52
+ apso do
53
+ mlcl do
54
+ mlit do
55
+ cann 'foo'
56
+ end
57
+ mlit do
58
+ cann 'bar'
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
64
+
65
+ it "handles the special case for ceJV" do
66
+ # ceJV is a 4 byte integer field but seems to store the value as a short in the first two bytes
67
+ DMAP.build do
68
+ mlit do # dmap.listingitem
69
+ mikd 2 # dmap.itemkind
70
+ asal "Aquarium" # daap.songalbum
71
+ asar "Naomi" # daap.songartist
72
+ miid 3123 # dmap.itemid
73
+ minm "Relax She Said" # dmap.itemname
74
+ mper 9013529250002063060 # dmap.persistentid
75
+ mcti 10386 # dmap.containeritemid
76
+ aeHV 0 # com.apple.itunes.has-video
77
+ asai 9013529250002063588 # daap.songalbumid
78
+ ceJV 2 # com.apple.itunes.jukebox-vote
79
+ ceJC 1 # com.apple.itunes.jukebox-client-vote
80
+ end
81
+ end.to_dmap.should == "mlit\000\000\000\222mikd\000\000\000\001\002asal\000\000\000\bAquariumasar\000\000\000\005Naomimiid\000\000\000\004\000\000\f3minm\000\000\000\016Relax She Saidmper\000\000\000\b}\026}\030\336\367N\324mcti\000\000\000\004\000\000(\222aeHV\000\000\000\001\000asai\000\000\000\b}\026}\030\336\367P\344ceJV\000\000\000\004\000\002\000\000ceJC\000\000\000\001\001"
82
+ end
83
+
84
+ it "builds a valid /databases aply tag" do
85
+ DMAP.build do
86
+ aply do
87
+ mstt 200 # Status
88
+ muty 0 # Update type
89
+ mtco 2 # Total count
90
+ mrco 2 # Return count
91
+ mlcl do # Container
92
+ mlit do # Container item
93
+ miid 10310 # Item ID
94
+ mper 123 # Persistent ID
95
+ minm 'Music' # Container name
96
+ aeSP true # Smart playlist
97
+ mpco 0 # Parent ID, so therefore parent container
98
+ aePS 6 # Special playlist type/ID
99
+ meds 0 # Edit commands supported
100
+ mimc 2 # Item/Song count
101
+ end
102
+ mlit do # Container item
103
+ miid 10281
104
+ mper 1234
105
+ minm 'iTunes DJ'
106
+ mpco 0 # Parent ID
107
+ aePS 2 # Spcial playlist type/ID
108
+ meds 0 # Edit commands supported
109
+ ceJI 0x282c # Current jukebox song ID?
110
+ mimc 18 # Item/song count
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
116
+
117
+ it "builds a valid caci tag" do
118
+ DMAP.build do
119
+ caci do # Some container
120
+ mstt 200 # Status
121
+ muty 0 # Update type
122
+ mtco 1 # Total count
123
+ mrco 1 # Return count
124
+ mlcl do # Container
125
+ mlit do # Container item
126
+ miid 1 # ID
127
+ cmik 1 # ??
128
+ cmsp 1 # ??
129
+ end
130
+ end
131
+ end
132
+ end.to_dmap
133
+ end
134
+ end
135
+
136
+
137
+ end
@@ -0,0 +1,96 @@
1
+ require 'dmap'
2
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
3
+
4
+ describe DMAP::Parser do
5
+ describe "#initialize" do
6
+ it "parses a simple DMAP" do
7
+ DMAP.parse("ceWM\000\000\000\003sup").should == DMAP.build do
8
+ ceWM 'sup'
9
+ end
10
+ end
11
+
12
+ it "parses a nested DMAP" do
13
+ DMAP.parse("msml\000\000\0000msma\000\000\000\b\000\000\314W\272\302\036\000msma\000\000\000\b\000\000\307sP\363\037\000").should == DMAP.build do
14
+ msml do
15
+ msma 224677167504896
16
+ msma 219298093276928
17
+ end
18
+ end
19
+ end
20
+
21
+ describe "new tags" do
22
+ it "parses mlit (playlist entry)" do
23
+ DMAP.parse("mlit\000\000\000\222mikd\000\000\000\001\002asal\000\000\000\bAquariumasar\000\000\000\005Naomimiid\000\000\000\004\000\000\f3minm\000\000\000\016Relax She Saidmper\000\000\000\b}\026}\030\336\367N\324mcti\000\000\000\004\000\000(\222aeHV\000\000\000\001\000asai\000\000\000\b}\026}\030\336\367P\344ceJV\000\000\000\004\000\002\000\000ceJC\000\000\000\001\001").should == DMAP.build do
24
+
25
+ mlit do # dmap.listingitem
26
+ mikd 2 # dmap.itemkind
27
+ asal "Aquarium" # daap.songalbum
28
+ asar "Naomi" # daap.songartist
29
+ miid 3123 # dmap.itemid
30
+ minm "Relax She Said" # dmap.itemname
31
+ mper 9013529250002063060 # dmap.persistentid
32
+ mcti 10386 # dmap.containeritemid
33
+ aeHV 0 # com.apple.itunes.has-video
34
+ asai 9013529250002063588 # daap.songalbumid
35
+ ceJV 2 # com.apple.itunes.jukebox-vote
36
+ ceJC 1 # com.apple.itunes.jukebox-client-vote
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+ it "parses cgmt" do
43
+ DMAP.parse("cmgt\000\000\000\030mstt\000\000\000\004\000\000\000\310cmvo\000\000\000\004\000\000\000X"
44
+ ).should == DMAP.build do
45
+ cmgt do
46
+ mstt 200 # Status
47
+ cmvo 88 # Volume
48
+ end
49
+ end
50
+ end
51
+
52
+ it "parses caci" do
53
+ DMAP.parse("caci\000\000\000[mstt\000\000\000\004\000\000\000\310muty\000\000\000\001\000mtco\000\000\000\004\000\000\000\001mrco\000\000\000\004\000\000\000\001mlcl\000\000\000&mlit\000\000\000\036miid\000\000\000\004\000\000\000\001cmik\000\000\000\001\001cmsp\000\000\000\001\001").should == DMAP.build do
54
+ caci do # Some container
55
+ mstt 200 # Status
56
+ muty 0 # Update type
57
+ mtco 1 # Total count
58
+ mrco 1 # Return count
59
+ mlcl do # Container
60
+ mlit do # Container item
61
+ miid 1 # ID
62
+ cmik 1 # ??
63
+ cmsp 1 # ??
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
69
+
70
+ it "parses cmst (player status)" do
71
+ DMAP.parse("cmst\000\000\001%mstt\000\000\000\004\000\000\000\310cmsr\000\000\000\004\000\000\000'caps\000\000\000\001\003cash\000\000\000\001\000carp\000\000\000\001\000cavc\000\000\000\001\001caas\000\000\000\004\000\000\000\002caar\000\000\000\004\000\000\000\006canp\000\000\000\020\000\000\000'\000\000(F\000\000(\266\000\000\016\375cann\000\000\000/Who Needs Forever? (Thievery Corporation remix)cana\000\000\000\017Astrud Gilbertocanl\000\000\000\rVerve Remixedcang\000\000\000\021Electronica/Danceasai\000\000\000\b}\026}\030\336\367Q\035cmmk\000\000\000\004\000\000\000\001ceGS\000\000\000\001\001cant\000\000\000\004\000\002 Gcast\000\000\000\004\000\003\335\024").should == DMAP.build do
72
+ cmst do
73
+ mstt 200 # Status
74
+ cmsr 39 # Revision
75
+ caps 3 # Player state
76
+ cash 0 # Shuffle state
77
+ carp 0 # Repeat state
78
+ cavc 1 # Volume controllable
79
+ caas 2 # Avaliable shuffle states
80
+ caar 6 # Avaliable repeat states
81
+ canp "\000\000\000'\000\000(F\000\000(\266\000\000\016\375" # ??
82
+ cann "Who Needs Forever? (Thievery Corporation remix)" # Track name
83
+ cana "Astrud Gilberto" # Track artist
84
+ canl "Verve Remixed" # Track album
85
+ cang "Electronica/Dance" # Track genre
86
+ asai 9013529250002063645 # ??
87
+ cmmk 1 # ??
88
+ ceGS 1 # ?? something to do with DJ
89
+ cant 139335 # elapsed play time in milliseconds
90
+ cast 253204 # total play time in milliseconds
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,57 @@
1
+ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
2
+
3
+ describe "Selectors" do
4
+ subject do
5
+ @expected = DMAP.build do
6
+ caci do # Some container
7
+ mstt 200 # Status
8
+ muty 0 # Update type
9
+ mtco 1 # Total count
10
+ mrco 1 # Return count
11
+ ceWM 'some string'
12
+ mlcl do # Container
13
+ mlit do # Container item
14
+ miid 1 # ID
15
+ cmik 1 # ??
16
+ cmsp 1 # ??
17
+ end
18
+ mlit do # Container item
19
+ miid 2 # ID
20
+ cmik 1 # ??
21
+ cmsp 1 # ??
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ it "selects individual tags" do
29
+ subject.mstt.should == 200
30
+ subject.ceWM.should == 'some string'
31
+ end
32
+
33
+ it "selects array tags" do
34
+ subject.mlcl.should == DMAP.build do
35
+ mlit do # Container item
36
+ miid 1 # ID
37
+ cmik 1 # ??
38
+ cmsp 1 # ??
39
+ end
40
+ mlit do # Container item
41
+ miid 2 # ID
42
+ cmik 1 # ??
43
+ cmsp 1 # ??
44
+ end
45
+ end
46
+ end
47
+
48
+ it "selects array elements" do
49
+ subject.mlcl[0].should == DMAP.build do
50
+ mlit do # Container item
51
+ miid 1 # ID
52
+ cmik 1 # ??
53
+ cmsp 1 # ??
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1 @@
1
+ --color
@@ -0,0 +1,9 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
3
+ require 'dmap'
4
+ require 'spec'
5
+ require 'spec/autorun'
6
+
7
+ Spec::Runner.configure do |config|
8
+
9
+ end
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dmap-ng
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 2
8
+ - 5
9
+ version: 0.2.5
10
+ platform: ruby
11
+ authors:
12
+ - Jack Chen
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-19 00:00:00 +10:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rspec
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 2
30
+ - 9
31
+ version: 1.2.9
32
+ type: :development
33
+ version_requirements: *id001
34
+ description: An improved DMAP gem that allows easy building and parsing of DMAP structures
35
+ email: chendo@chendo.net
36
+ executables: []
37
+
38
+ extensions: []
39
+
40
+ extra_rdoc_files:
41
+ - LICENSE
42
+ - README.md
43
+ files:
44
+ - .document
45
+ - .gitignore
46
+ - LICENSE
47
+ - README.md
48
+ - Rakefile
49
+ - VERSION
50
+ - dmap-ng.gemspec
51
+ - lib/debug_ext.rb
52
+ - lib/dmap-ng.rb
53
+ - lib/dmap.rb
54
+ - lib/dmap/parser.rb
55
+ - lib/dmap/tag.rb
56
+ - lib/dmap/tag_builder.rb
57
+ - lib/dmap/tag_definitions.rb
58
+ - lib/true_false_ext.rb
59
+ - spec/dmap_spec.rb
60
+ - spec/dsl_spec.rb
61
+ - spec/packet_dumps/connection_with_voting.dump
62
+ - spec/parser_spec.rb
63
+ - spec/selector_spec.rb
64
+ - spec/spec.opts
65
+ - spec/spec_helper.rb
66
+ has_rdoc: true
67
+ homepage: http://github.com/chendo/dmap-ng
68
+ licenses: []
69
+
70
+ post_install_message:
71
+ rdoc_options:
72
+ - --charset=UTF-8
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ requirements: []
90
+
91
+ rubyforge_project:
92
+ rubygems_version: 1.3.6
93
+ signing_key:
94
+ specification_version: 3
95
+ summary: An improved DMAP gem that allows easy building and parsing of DMAP structures
96
+ test_files:
97
+ - spec/dmap_spec.rb
98
+ - spec/dsl_spec.rb
99
+ - spec/parser_spec.rb
100
+ - spec/selector_spec.rb
101
+ - spec/spec_helper.rb