rbpod 0.0.4 → 0.0.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.
- data/README.md +9 -9
- data/Rakefile +5 -3
- data/ext/rbpod/collection.c +58 -60
- data/ext/rbpod/collection.h +1 -3
- data/ext/rbpod/database.c +46 -15
- data/ext/rbpod/device.c +2 -1
- data/ext/rbpod/error.c +27 -0
- data/ext/rbpod/error.h +12 -0
- data/ext/rbpod/playlist.c +14 -22
- data/ext/rbpod/playlist_collection.c +74 -41
- data/ext/rbpod/playlist_collection.h +1 -5
- data/ext/rbpod/rbpod.c +35 -23
- data/ext/rbpod/rbpod.h +3 -1
- data/ext/rbpod/track_collection.c +38 -10
- data/ext/rbpod/track_collection.h +1 -5
- data/lib/rbpod/version.rb +1 -1
- data/spec/rbpod/collection_spec.rb +25 -0
- data/spec/{database_spec.rb → rbpod/database_spec.rb} +14 -21
- data/spec/rbpod/device_spec.rb +70 -0
- data/spec/rbpod/playlist_collection_spec.rb +44 -0
- data/spec/{playlist_spec.rb → rbpod/playlist_spec.rb} +1 -1
- data/spec/rbpod/track_collection_spec.rb +15 -0
- data/spec/{track_spec.rb → rbpod/track_spec.rb} +1 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/support/shared_contexts.rb +18 -0
- metadata +24 -16
- data/spec/collection_spec.rb +0 -39
- data/spec/device_spec.rb +0 -83
- /data/spec/{rbpod_spec.rb → rbpod/rbpod_spec.rb} +0 -0
data/README.md
CHANGED
@@ -70,12 +70,12 @@ device['PotsdamConf45'] = "Kilroy Was Here"
|
|
70
70
|
device.save!
|
71
71
|
```
|
72
72
|
|
73
|
-
### RbPod::
|
73
|
+
### RbPod::PlaylistCollection
|
74
74
|
|
75
|
-
|
75
|
+
You can get direct access to the playlists on the device:
|
76
76
|
|
77
77
|
```ruby
|
78
|
-
database.playlists # => #<RbPod::
|
78
|
+
database.playlists # => #<RbPod::PlaylistCollection:0xdeadbeef>
|
79
79
|
|
80
80
|
# For a list of all the names of playlists on the iPod:
|
81
81
|
database.playlists.map(&:name) # => ["iPod", "Podcasts", "Recently Added"]
|
@@ -83,8 +83,8 @@ database.playlists.map(&:name) # => ["iPod", "Podcasts", "Recently Added"]
|
|
83
83
|
# For direct access to the master playlist:
|
84
84
|
database.playlists.master # => #<RbPod::Playlist:0xdeadbeef>
|
85
85
|
|
86
|
-
# For direct access to the
|
87
|
-
database.playlists.
|
86
|
+
# For direct access to the podcast playlist:
|
87
|
+
database.playlists.podcast # => #<RbPod::Playlist:0xdeadbeef>
|
88
88
|
```
|
89
89
|
|
90
90
|
### RbPod::Playlist
|
@@ -98,11 +98,11 @@ playlist.name # => "iPod"
|
|
98
98
|
playlist.length # => 400
|
99
99
|
playlist.created_on # => 2008-04-05 08:47:46 -0700
|
100
100
|
|
101
|
-
playlist.
|
102
|
-
playlist.
|
103
|
-
playlist.
|
101
|
+
playlist.master? # => true
|
102
|
+
playlist.smart? # => false
|
103
|
+
playlist.podcast? # => false
|
104
104
|
|
105
|
-
playlist.tracks # => #<RbPod::
|
105
|
+
playlist.tracks # => #<RbPod::TrackCollection:0xdeadbeef>
|
106
106
|
```
|
107
107
|
|
108
108
|
### RbPod::Track
|
data/Rakefile
CHANGED
@@ -13,8 +13,8 @@ require 'rspec/core/rake_task'
|
|
13
13
|
# Bring in RDoc's built-in rake task.
|
14
14
|
require 'rdoc/task'
|
15
15
|
|
16
|
-
# By default,
|
17
|
-
task :default => [ :
|
16
|
+
# By default, run rspec tests.
|
17
|
+
task :default => [ :test ]
|
18
18
|
|
19
19
|
# Let Rake know what is safe to remove.
|
20
20
|
CLEAN.include [ 'pkg/*', 'doc/*' ]
|
@@ -27,7 +27,7 @@ Rake::ExtensionTask.new do |extension|
|
|
27
27
|
extension.lib_dir = 'lib/rbpod'
|
28
28
|
|
29
29
|
# Monitor sources for change tracking.
|
30
|
-
extension.source_pattern = '*.
|
30
|
+
extension.source_pattern = '*.[ch]'
|
31
31
|
end
|
32
32
|
|
33
33
|
desc "Run all available RSpec tests."
|
@@ -36,6 +36,8 @@ RSpec::Core::RakeTask.new(:test) do |task|
|
|
36
36
|
# Execute ruby with warnings enabled.
|
37
37
|
task.ruby_opts = '-w'
|
38
38
|
end
|
39
|
+
# Make compilation a prerequisite of testing.
|
40
|
+
Rake::Task[:test].prerequisites << :compile
|
39
41
|
|
40
42
|
desc "Build all RDoc documentation."
|
41
43
|
RDoc::Task.new(:rdoc) do |task|
|
data/ext/rbpod/collection.c
CHANGED
@@ -3,37 +3,28 @@
|
|
3
3
|
#include "rbpod.h"
|
4
4
|
#include "collection.h"
|
5
5
|
|
6
|
-
struct collection {
|
7
|
-
VALUE klass;
|
8
|
-
GList *list;
|
9
|
-
};
|
10
|
-
|
11
|
-
inline VALUE rbpod_collection_create(GList *list, VALUE type)
|
12
|
-
{
|
13
|
-
struct collection *collection = ALLOC(struct collection);
|
14
|
-
collection->list = list;
|
15
|
-
collection->klass = type;
|
16
|
-
return Data_Wrap_Struct(cRbPodCollection, NULL, NULL, (void *) collection);
|
17
|
-
}
|
18
|
-
|
19
6
|
/*
|
20
7
|
* call-seq:
|
21
8
|
* [](index) -> Object or nil
|
22
9
|
*
|
23
|
-
*
|
10
|
+
* Given an integer +index+, return the item at that position in the collection.
|
24
11
|
*/
|
25
12
|
static VALUE rbpod_collection_get(VALUE self, VALUE key)
|
26
13
|
{
|
27
|
-
|
28
|
-
|
14
|
+
GList *current = NULL, *collection = TYPED_DATA_PTR(self, GList);
|
15
|
+
VALUE klass = rb_funcall(self, rb_intern("type"), 0);
|
29
16
|
|
30
17
|
if (FIXNUM_P(key) == FALSE) {
|
31
18
|
return Qnil;
|
32
19
|
}
|
33
20
|
|
34
|
-
current = g_list_nth(collection
|
21
|
+
current = g_list_nth(collection, FIX2INT(key));
|
35
22
|
|
36
|
-
|
23
|
+
if (current == NULL) {
|
24
|
+
return Qnil;
|
25
|
+
}
|
26
|
+
|
27
|
+
return rb_class_new_instance_with_data(0, NULL, klass, current->data);
|
37
28
|
}
|
38
29
|
|
39
30
|
/*
|
@@ -44,14 +35,15 @@ static VALUE rbpod_collection_get(VALUE self, VALUE key)
|
|
44
35
|
*/
|
45
36
|
static VALUE rbpod_collection_last(VALUE self)
|
46
37
|
{
|
47
|
-
|
48
|
-
GList *
|
38
|
+
VALUE klass = rb_funcall(self, rb_intern("type"), 0);
|
39
|
+
GList *collection = TYPED_DATA_PTR(self, GList);
|
40
|
+
GList *current = g_list_last(collection);
|
49
41
|
|
50
42
|
if (current == NULL) {
|
51
43
|
return Qnil;
|
52
44
|
}
|
53
45
|
|
54
|
-
return
|
46
|
+
return rb_class_new_instance_with_data(0, NULL, klass, current->data);
|
55
47
|
}
|
56
48
|
|
57
49
|
/*
|
@@ -62,26 +54,27 @@ static VALUE rbpod_collection_last(VALUE self)
|
|
62
54
|
*/
|
63
55
|
static VALUE rbpod_collection_first(VALUE self)
|
64
56
|
{
|
65
|
-
|
66
|
-
GList *
|
57
|
+
VALUE klass = rb_funcall(self, rb_intern("type"), 0);
|
58
|
+
GList *collection = TYPED_DATA_PTR(self, GList);
|
59
|
+
GList *current = g_list_first(collection);
|
67
60
|
|
68
61
|
if (current == NULL) {
|
69
62
|
return Qnil;
|
70
63
|
}
|
71
64
|
|
72
|
-
return
|
65
|
+
return rb_class_new_instance_with_data(0, NULL, klass, current->data);
|
73
66
|
}
|
74
67
|
|
75
68
|
/*
|
76
69
|
* call-seq:
|
77
|
-
*
|
70
|
+
* size() -> Integer
|
78
71
|
*
|
79
72
|
* Return the total length of all items in the collection.
|
80
73
|
*/
|
81
|
-
static VALUE
|
74
|
+
static VALUE rbpod_collection_size(VALUE self)
|
82
75
|
{
|
83
|
-
|
84
|
-
return INT2NUM(g_list_length(collection
|
76
|
+
GList *collection = TYPED_DATA_PTR(self, GList);
|
77
|
+
return INT2NUM(g_list_length(collection));
|
85
78
|
}
|
86
79
|
|
87
80
|
/*
|
@@ -95,19 +88,25 @@ static VALUE rbpod_collection_length(VALUE self)
|
|
95
88
|
*/
|
96
89
|
static VALUE rbpod_collection_each(VALUE self, VALUE argv)
|
97
90
|
{
|
98
|
-
|
99
|
-
VALUE item
|
100
|
-
GList *current = NULL;
|
91
|
+
GList *current = NULL, *collection = TYPED_DATA_PTR(self, GList);
|
92
|
+
VALUE klass, item, arguments;
|
101
93
|
|
102
94
|
/* Return an enumerator if a block was not supplied. */
|
103
95
|
RETURN_ENUMERATOR(self, 0, 0);
|
104
96
|
|
97
|
+
/* What sort of items are we casting this data to? */
|
98
|
+
klass = rb_funcall(self, rb_intern("type"), 0);
|
99
|
+
|
100
|
+
/* Create a shallow copy of the passed arguments. */
|
101
|
+
arguments = rb_ary_dup(argv);
|
102
|
+
|
105
103
|
/* Prepend an empty element as a placeholder. */
|
106
104
|
rb_ary_unshift(arguments, Qnil);
|
107
105
|
|
108
106
|
/* If we were supplied a block, enumerate the entire list. */
|
109
|
-
for (current = collection
|
110
|
-
|
107
|
+
for (current = collection; current != NULL; current = g_list_next(current)) {
|
108
|
+
/* TODO: Find a better workaround than this or Data_Wrap_Struct. */
|
109
|
+
item = rb_class_new_instance_with_data(0, NULL, klass, current->data);
|
111
110
|
rb_ary_store(arguments, 0, item);
|
112
111
|
rb_yield_splat(arguments);
|
113
112
|
}
|
@@ -115,24 +114,28 @@ static VALUE rbpod_collection_each(VALUE self, VALUE argv)
|
|
115
114
|
return self;
|
116
115
|
}
|
117
116
|
|
118
|
-
|
117
|
+
/*
|
118
|
+
* :nodoc:
|
119
|
+
*/
|
120
|
+
static VALUE rbpod_collection_type(VALUE self)
|
119
121
|
{
|
120
|
-
|
121
|
-
|
122
|
-
if (collection->list != NULL) {
|
123
|
-
g_list_free(collection->list);
|
124
|
-
}
|
125
|
-
|
126
|
-
xfree(handle);
|
127
|
-
return;
|
122
|
+
/* We should get an error if we try to create an instance of NilClass. */
|
123
|
+
return Qnil;
|
128
124
|
}
|
129
125
|
|
130
|
-
|
126
|
+
/*
|
127
|
+
* :nodoc:
|
128
|
+
*/
|
129
|
+
static VALUE rbpod_collection_included(VALUE self, VALUE other)
|
131
130
|
{
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
131
|
+
/* Collections should be Enumerable and Comparable. */
|
132
|
+
rb_include_module(other, rb_mEnumerable);
|
133
|
+
rb_include_module(other, rb_mComparable);
|
134
|
+
|
135
|
+
/* Override Enumerable with our methods. */
|
136
|
+
rb_extend_object(other, self);
|
137
|
+
|
138
|
+
return self;
|
136
139
|
}
|
137
140
|
|
138
141
|
void Init_rbpod_collection(void)
|
@@ -140,22 +143,17 @@ void Init_rbpod_collection(void)
|
|
140
143
|
#if RDOC_CAN_PARSE_DOCUMENTATION
|
141
144
|
mRbPod = rb_define_module("RbPod");
|
142
145
|
#endif
|
143
|
-
|
144
|
-
|
145
|
-
rb_define_alloc_func(cRbPodCollection, rbpod_collection_allocate);
|
146
|
-
|
147
|
-
rb_include_module(cRbPodCollection, rb_mEnumerable);
|
148
|
-
rb_include_module(cRbPodCollection, rb_mComparable);
|
146
|
+
mRbPodCollection = rb_define_module_under(mRbPod, "Collection");
|
149
147
|
|
150
|
-
|
148
|
+
rb_define_singleton_method(mRbPodCollection, "included", rbpod_collection_included, 1);
|
151
149
|
|
152
|
-
|
150
|
+
rb_define_private_method(mRbPodCollection, "type", rbpod_collection_type, 0);
|
153
151
|
|
154
|
-
|
155
|
-
|
152
|
+
rb_define_method(mRbPodCollection, "each", rbpod_collection_each, -2);
|
153
|
+
rb_define_method(mRbPodCollection, "size", rbpod_collection_size, 0);
|
156
154
|
|
157
|
-
rb_define_method(
|
158
|
-
rb_define_method(
|
155
|
+
rb_define_method(mRbPodCollection, "first", rbpod_collection_first, 0);
|
156
|
+
rb_define_method(mRbPodCollection, "last", rbpod_collection_last, 0);
|
159
157
|
|
160
|
-
rb_define_method(
|
158
|
+
rb_define_method(mRbPodCollection, "[]", rbpod_collection_get, 1);
|
161
159
|
}
|
data/ext/rbpod/collection.h
CHANGED
@@ -3,10 +3,8 @@
|
|
3
3
|
#ifndef RBPOD_COLLECTION_H
|
4
4
|
#define RBPOD_COLLECTION_H
|
5
5
|
|
6
|
-
RUBY_EXTERN VALUE
|
6
|
+
RUBY_EXTERN VALUE mRbPodCollection;
|
7
7
|
|
8
8
|
void Init_rbpod_collection(void);
|
9
9
|
|
10
|
-
inline VALUE rbpod_collection_create(GList *list, VALUE type);
|
11
|
-
|
12
10
|
#endif /* RBPOD_COLLECTION_H */
|
data/ext/rbpod/database.c
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
/* database.c */
|
2
2
|
|
3
3
|
#include "rbpod.h"
|
4
|
+
#include "error.h"
|
4
5
|
#include "device.h"
|
5
6
|
#include "database.h"
|
7
|
+
#include "playlist.h"
|
6
8
|
#include "track_collection.h"
|
7
9
|
#include "playlist_collection.h"
|
8
10
|
|
@@ -39,22 +41,26 @@ static VALUE rbpod_database_synchronized_p(VALUE self)
|
|
39
41
|
|
40
42
|
/*
|
41
43
|
* call-seq:
|
42
|
-
* playlists() -> RbPod::
|
44
|
+
* playlists() -> RbPod::PlaylistCollection
|
43
45
|
*
|
44
46
|
* Returns a collection of all playlists added to this database.
|
45
47
|
*/
|
46
48
|
static VALUE rbpod_database_playlists_get(VALUE self)
|
47
49
|
{
|
48
|
-
|
49
|
-
return rbpod_playlist_collection_create(self, database->playlists);
|
50
|
+
return rb_class_new_instance(1, &self, cRbPodPlaylistCollection);
|
50
51
|
}
|
51
52
|
|
53
|
+
/*
|
54
|
+
* call-seq:
|
55
|
+
* tracks() -> RbPod::TrackCollection
|
56
|
+
*
|
57
|
+
* Returns a collection of all tracks added to this database.
|
58
|
+
*/
|
52
59
|
static VALUE rbpod_database_tracks_get(VALUE self)
|
53
60
|
{
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
return rbpod_track_collection_create(parent, database->tracks);
|
61
|
+
VALUE playlists = rbpod_database_playlists_get(self);
|
62
|
+
VALUE master = rb_funcall(playlists, rb_intern("master"), 0);
|
63
|
+
return rb_class_new_instance(1, &master, cRbPodTrackCollection);
|
58
64
|
}
|
59
65
|
|
60
66
|
/*
|
@@ -93,6 +99,9 @@ static VALUE rbpod_database_version_get(VALUE self)
|
|
93
99
|
return INT2NUM(database->version);
|
94
100
|
}
|
95
101
|
|
102
|
+
/*
|
103
|
+
* :nodoc:
|
104
|
+
*/
|
96
105
|
static VALUE rbpod_database_id_get(VALUE self)
|
97
106
|
{
|
98
107
|
Itdb_iTunesDB *database = TYPED_DATA_PTR(self, Itdb_iTunesDB);
|
@@ -112,6 +121,9 @@ static VALUE rbpod_database_mountpoint_get(VALUE self)
|
|
112
121
|
return rb_class_new_instance(1, &mount_point, rb_cPathname);
|
113
122
|
}
|
114
123
|
|
124
|
+
/*
|
125
|
+
* :nodoc:
|
126
|
+
*/
|
115
127
|
static VALUE rbpod_database_mountpoint_set(VALUE self, VALUE path)
|
116
128
|
{
|
117
129
|
Itdb_iTunesDB *database = TYPED_DATA_PTR(self, Itdb_iTunesDB);
|
@@ -137,6 +149,12 @@ static VALUE rbpod_database_initialize(VALUE self, VALUE mount_point)
|
|
137
149
|
Itdb_iTunesDB *previous = database;
|
138
150
|
GError *error = NULL;
|
139
151
|
|
152
|
+
/* Check if the mount point is a directory. */
|
153
|
+
if (rb_file_directory_p(rb_cFile, mount_point) != Qtrue) {
|
154
|
+
rb_raise(eRbPodError, "The mount point must be a directory!");
|
155
|
+
return Qnil;
|
156
|
+
}
|
157
|
+
|
140
158
|
/* Try to parse the database from the given mount point. */
|
141
159
|
database = itdb_parse(StringValueCStr(mount_point), &error);
|
142
160
|
|
@@ -170,6 +188,7 @@ static VALUE rbpod_database_allocate(VALUE self)
|
|
170
188
|
static VALUE rbpod_database_create(int argc, VALUE *argv, VALUE self)
|
171
189
|
{
|
172
190
|
gchar *_mount_point, *_device_name, *_model_number;
|
191
|
+
VALUE model_matcher, model_regexp, ignorecase;
|
173
192
|
VALUE mount_point, device_name, model_number;
|
174
193
|
GError *error = NULL;
|
175
194
|
|
@@ -185,19 +204,30 @@ static VALUE rbpod_database_create(int argc, VALUE *argv, VALUE self)
|
|
185
204
|
}
|
186
205
|
|
187
206
|
/* If we didn't specify a device name, default to 'iPod'. */
|
188
|
-
if (RTEST(device_name)
|
189
|
-
rb_raise(eRbPodError, "Device name should be a string of at least three characters.");
|
190
|
-
return Qnil;
|
191
|
-
} else {
|
207
|
+
if (RTEST(device_name) == FALSE) {
|
192
208
|
device_name = rb_str_new2("iPod");
|
193
209
|
}
|
194
210
|
|
195
|
-
/*
|
196
|
-
if (
|
197
|
-
rb_raise(eRbPodError, "
|
211
|
+
/* Ensure it's a valid device name, if it was given. */
|
212
|
+
if (TYPE(device_name) == T_STRING && RSTRING_LEN(device_name) == 0) {
|
213
|
+
rb_raise(eRbPodError, "Device name must not be an empty string.");
|
198
214
|
return Qnil;
|
199
215
|
}
|
200
216
|
|
217
|
+
/* If a model number was given, ensure it's a string. */
|
218
|
+
if (RTEST(model_number)) {
|
219
|
+
Check_Type(device_name, T_STRING);
|
220
|
+
|
221
|
+
model_matcher = rb_str_new2("/x?[A-Z][0-9]{3}/");
|
222
|
+
ignorecase = rb_const_get(rb_cRegexp, rb_intern("IGNORECASE"));
|
223
|
+
model_regexp = rb_reg_new_str(model_matcher, ignorecase);
|
224
|
+
|
225
|
+
if (RTEST(rb_reg_match(model_regexp, model_number)) == FALSE) {
|
226
|
+
rb_raise(eRbPodError, "Model number must be a string matching: /x?[A-Z][0-9]{3}/i");
|
227
|
+
return Qnil;
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
201
231
|
/* Extract pointers for glib use. */
|
202
232
|
_mount_point = StringValueCStr(mount_point);
|
203
233
|
_device_name = StringValueCStr(device_name);
|
@@ -228,7 +258,6 @@ void Init_rbpod_database(void)
|
|
228
258
|
rb_define_singleton_method(cRbPodDatabase, "create!", rbpod_database_create, -1);
|
229
259
|
|
230
260
|
rb_define_private_method(cRbPodDatabase, "id", rbpod_database_id_get, 0);
|
231
|
-
rb_define_private_method(cRbPodDatabase, "tracks", rbpod_database_tracks_get, 0);
|
232
261
|
rb_define_private_method(cRbPodDatabase, "mountpoint=", rbpod_database_mountpoint_set, 1);
|
233
262
|
|
234
263
|
rb_define_method(cRbPodDatabase, "mountpoint", rbpod_database_mountpoint_get, 0);
|
@@ -237,6 +266,8 @@ void Init_rbpod_database(void)
|
|
237
266
|
rb_define_method(cRbPodDatabase, "filename", rbpod_database_filename_get, 0);
|
238
267
|
|
239
268
|
rb_define_method(cRbPodDatabase, "device", rbpod_database_device_get, 0);
|
269
|
+
|
270
|
+
rb_define_method(cRbPodDatabase, "tracks", rbpod_database_tracks_get, 0);
|
240
271
|
rb_define_method(cRbPodDatabase, "playlists", rbpod_database_playlists_get, 0);
|
241
272
|
|
242
273
|
rb_define_method(cRbPodDatabase, "synchronized?", rbpod_database_synchronized_p, 0);
|
data/ext/rbpod/device.c
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
/* device.c */
|
2
2
|
|
3
3
|
#include "rbpod.h"
|
4
|
+
#include "error.h"
|
4
5
|
#include "device.h"
|
5
6
|
#include "database.h"
|
6
7
|
|
@@ -197,7 +198,7 @@ static VALUE rbpod_device_initialize(VALUE self, VALUE database)
|
|
197
198
|
Itdb_iTunesDB *_database = TYPED_DATA_PTR(database, Itdb_iTunesDB);
|
198
199
|
|
199
200
|
/* Make sure we were given an instance of a RbPod::Database. */
|
200
|
-
if (
|
201
|
+
if (rb_obj_is_instance_of(database, cRbPodDatabase) == FALSE) {
|
201
202
|
rb_raise(eRbPodError, "Given database must be an instance of RbPod::Database: %s", StringValueCStr(database));
|
202
203
|
return Qnil;
|
203
204
|
}
|
data/ext/rbpod/error.c
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
/* error.c */
|
2
|
+
|
3
|
+
#include "rbpod.h"
|
4
|
+
#include "error.h"
|
5
|
+
|
6
|
+
inline VALUE rbpod_raise_error(GError *error)
|
7
|
+
{
|
8
|
+
VALUE error_message;
|
9
|
+
|
10
|
+
if (error != NULL) {
|
11
|
+
error_message = rb_str_new2(error->message);
|
12
|
+
g_error_free(error);
|
13
|
+
rb_raise(eRbPodError, "%s", StringValueCStr(error_message));
|
14
|
+
}
|
15
|
+
|
16
|
+
return Qnil;
|
17
|
+
}
|
18
|
+
|
19
|
+
void Init_rbpod_error(void)
|
20
|
+
{
|
21
|
+
#if RDOC_CAN_PARSE_DOCUMENTATION
|
22
|
+
mRbPod = rb_define_module("RbPod");
|
23
|
+
#endif
|
24
|
+
/* This is a generic subclass of RuntimeError for RbPod-specific errors.*/
|
25
|
+
eRbPodError = rb_define_class_under(mRbPod, "Error", rb_eRuntimeError);
|
26
|
+
}
|
27
|
+
|
data/ext/rbpod/error.h
ADDED
data/ext/rbpod/playlist.c
CHANGED
@@ -6,7 +6,7 @@
|
|
6
6
|
|
7
7
|
/*
|
8
8
|
* call-seq:
|
9
|
-
*
|
9
|
+
* podcast?() -> Boolean
|
10
10
|
*
|
11
11
|
* Returns true or false if this playlist is the podcast-only playlist.
|
12
12
|
*/
|
@@ -18,7 +18,7 @@ static VALUE rbpod_playlist_podcast_p(VALUE self)
|
|
18
18
|
|
19
19
|
/*
|
20
20
|
* call-seq:
|
21
|
-
*
|
21
|
+
* master?() -> Boolean
|
22
22
|
*
|
23
23
|
* Returns true or false if this playlist is the master playlist.
|
24
24
|
*/
|
@@ -30,7 +30,7 @@ static VALUE rbpod_playlist_master_p(VALUE self)
|
|
30
30
|
|
31
31
|
/*
|
32
32
|
* call-seq:
|
33
|
-
*
|
33
|
+
* smart?() -> Boolean
|
34
34
|
*
|
35
35
|
* Returns true or false if this playlist is a smart playlist.
|
36
36
|
*/
|
@@ -74,8 +74,7 @@ static VALUE rbpod_playlist_shuffle_bang(VALUE self)
|
|
74
74
|
*/
|
75
75
|
static VALUE rbpod_playlist_tracks_get(VALUE self)
|
76
76
|
{
|
77
|
-
|
78
|
-
return rbpod_track_collection_create(self, playlist->members);
|
77
|
+
return rb_class_new_instance(1, &self, cRbPodTrackCollection);
|
79
78
|
}
|
80
79
|
|
81
80
|
/*
|
@@ -137,21 +136,13 @@ static VALUE rbpod_playlist_id_get(VALUE self)
|
|
137
136
|
|
138
137
|
/*
|
139
138
|
* call-seq:
|
140
|
-
* initialize(
|
139
|
+
* initialize() -> RbPod::Playlist
|
141
140
|
*
|
142
141
|
* Creates a detached playlist. (Not managed by the database.)
|
143
142
|
*/
|
144
|
-
static VALUE rbpod_playlist_initialize(VALUE self
|
143
|
+
static VALUE rbpod_playlist_initialize(VALUE self)
|
145
144
|
{
|
146
|
-
|
147
|
-
gchar *_playlist_name = StringValueCStr(playlist_name);
|
148
|
-
|
149
|
-
itdb_playlist_free(playlist);
|
150
|
-
|
151
|
-
playlist = itdb_playlist_new(_playlist_name, (smart_playlist == Qtrue) ? TRUE : FALSE);
|
152
|
-
|
153
|
-
DATA_PTR(self) = playlist;
|
154
|
-
|
145
|
+
/* Nothing to see here. */
|
155
146
|
return self;
|
156
147
|
}
|
157
148
|
|
@@ -160,7 +151,7 @@ static void rbpod_playlist_deallocate(void *handle)
|
|
160
151
|
Itdb_Playlist *playlist = (Itdb_Playlist *) handle;
|
161
152
|
|
162
153
|
/* This playlist was unmanaged, so free it manually. */
|
163
|
-
if (playlist->itdb == NULL
|
154
|
+
if (playlist->itdb == NULL) {
|
164
155
|
itdb_playlist_free(playlist);
|
165
156
|
}
|
166
157
|
|
@@ -169,7 +160,7 @@ static void rbpod_playlist_deallocate(void *handle)
|
|
169
160
|
|
170
161
|
static VALUE rbpod_playlist_allocate(VALUE self)
|
171
162
|
{
|
172
|
-
Itdb_Playlist *playlist = itdb_playlist_new("
|
163
|
+
Itdb_Playlist *playlist = itdb_playlist_new("New Playlist", FALSE);
|
173
164
|
return Data_Wrap_Struct(cRbPodPlaylist, NULL, rbpod_playlist_deallocate, (void *) playlist);
|
174
165
|
}
|
175
166
|
|
@@ -182,7 +173,7 @@ void Init_rbpod_playlist(void)
|
|
182
173
|
|
183
174
|
rb_define_alloc_func(cRbPodPlaylist, rbpod_playlist_allocate);
|
184
175
|
|
185
|
-
rb_define_method(cRbPodPlaylist, "initialize", rbpod_playlist_initialize,
|
176
|
+
rb_define_method(cRbPodPlaylist, "initialize", rbpod_playlist_initialize, 0);
|
186
177
|
|
187
178
|
rb_define_private_method(cRbPodPlaylist, "id", rbpod_playlist_id_get, 0);
|
188
179
|
|
@@ -194,11 +185,12 @@ void Init_rbpod_playlist(void)
|
|
194
185
|
rb_define_method(cRbPodPlaylist, "shuffle!", rbpod_playlist_shuffle_bang, 0);
|
195
186
|
rb_define_method(cRbPodPlaylist, "timestamp", rbpod_playlist_timestamp_get, 0);
|
196
187
|
|
188
|
+
/* :nodoc */
|
197
189
|
rb_define_alias(cRbPodPlaylist, "created_on", "timestamp");
|
198
190
|
|
199
|
-
rb_define_method(cRbPodPlaylist, "
|
200
|
-
rb_define_method(cRbPodPlaylist, "
|
201
|
-
rb_define_method(cRbPodPlaylist, "
|
191
|
+
rb_define_method(cRbPodPlaylist, "smart?", rbpod_playlist_smart_p, 0);
|
192
|
+
rb_define_method(cRbPodPlaylist, "master?", rbpod_playlist_master_p, 0);
|
193
|
+
rb_define_method(cRbPodPlaylist, "podcast?", rbpod_playlist_podcast_p, 0);
|
202
194
|
|
203
195
|
return;
|
204
196
|
}
|