dmap-ng 0.2.5

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.
@@ -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