quvi 0.0.1 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ext/quvi_ext/quvi_ext.c +235 -21
- data/lib/quvi.rb +58 -0
- data/lib/quvi/handle.rb +12 -2
- data/lib/quvi/version.rb +2 -2
- metadata +10 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: df4e609a0c156ac9c3078066ad4085bda633d045
|
4
|
+
data.tar.gz: 19b0599fbe1c32905cfa0037a55ba2c709785615
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f1f209a0b4fe186e218a788bb9552cdc037bbebb0f04d13d3cda2f424af0284c35dd0bc2e65f295c3c416ba3cffc80fda27bdd8d72f677e99ca7445307007880
|
7
|
+
data.tar.gz: c76c59aa666494cee48d5e3522df85dbfe280835d48c1721be25add4483f3cd23f851caa03c589af688d651ccc8ef57e1cb0354d9d2101ddb73d676d7ba3aa62
|
data/ext/quvi_ext/quvi_ext.c
CHANGED
@@ -14,14 +14,33 @@ VALUE qv_eError;
|
|
14
14
|
|
15
15
|
VALUE qv_DEFAULT_USER_AGENT;
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
17
|
+
VALUE qv_sym_any;
|
18
|
+
VALUE qv_sym_autoproxy;
|
19
|
+
VALUE qv_sym_media;
|
20
|
+
VALUE qv_sym_online;
|
21
|
+
VALUE qv_sym_playlist;
|
22
|
+
VALUE qv_sym_subtitle;
|
23
|
+
VALUE qv_sym_type;
|
24
|
+
VALUE qv_sym_user_agent;
|
25
|
+
VALUE qv_sym_export_format;
|
26
|
+
VALUE qv_sym_filepath;
|
27
|
+
VALUE qv_sym_domains;
|
28
|
+
VALUE qv_sym_sha1;
|
29
|
+
VALUE qv_sym_title;
|
30
|
+
VALUE qv_sym_id;
|
31
|
+
VALUE qv_sym_thumbnail_url;
|
32
|
+
VALUE qv_sym_start_time_ms;
|
33
|
+
VALUE qv_sym_duration_ms;
|
34
|
+
VALUE qv_sym_video_height;
|
35
|
+
VALUE qv_sym_video_width;
|
36
|
+
VALUE qv_sym_video_encoding;
|
37
|
+
VALUE qv_sym_video_bitrate_kbit_s;
|
38
|
+
VALUE qv_sym_audio_encoding;
|
39
|
+
VALUE qv_sym_audio_bitrate_kbit_s;
|
40
|
+
VALUE qv_sym_container;
|
41
|
+
VALUE qv_sym_url;
|
42
|
+
VALUE qv_sym_streams;
|
43
|
+
VALUE qv_sym_best;
|
25
44
|
|
26
45
|
typedef struct qv_handle_st
|
27
46
|
{
|
@@ -45,21 +64,21 @@ static void qv_handle_free(void *ptr)
|
|
45
64
|
}
|
46
65
|
|
47
66
|
#define qv_raise(handle, message) qv_raise_at(handle, message, __FILE__, __LINE__)
|
48
|
-
static void qv_raise_at(qv_handle_t *handle,
|
67
|
+
static void qv_raise_at(qv_handle_t *handle, VALUE message, const char *file, int line)
|
49
68
|
{
|
50
69
|
VALUE exc, str;
|
51
70
|
const char *qv_msg;
|
52
71
|
char buf[10];
|
53
72
|
int qv_code;
|
54
73
|
|
55
|
-
str =
|
74
|
+
str = rb_str_new_shared(message);
|
56
75
|
qv_msg = quvi_errmsg(handle->q);
|
57
76
|
qv_code = quvi_errcode(handle->q);
|
58
77
|
if (qv_msg) {
|
59
|
-
|
78
|
+
snprintf(buf, 10, ": (0x%02x) \"", qv_code);
|
79
|
+
rb_str_buf_cat_ascii(str, buf);
|
60
80
|
rb_str_buf_cat_ascii(str, qv_msg);
|
61
81
|
rb_str_buf_cat_ascii(str, "\" ");
|
62
|
-
snprintf(buf, 10, "\" (%d)", qv_code);
|
63
82
|
}
|
64
83
|
rb_str_buf_cat_ascii(str, " at ");
|
65
84
|
rb_str_buf_cat_ascii(str, file);
|
@@ -101,7 +120,7 @@ VALUE qv_handle_init(int argc, VALUE *argv, VALUE self)
|
|
101
120
|
}
|
102
121
|
handle->q = quvi_new();
|
103
122
|
if (quvi_ok(handle->q) == QUVI_FALSE) {
|
104
|
-
qv_raise(handle, "unable create quvi_t handle");
|
123
|
+
qv_raise(handle, rb_str_new_cstr("unable create quvi_t handle"));
|
105
124
|
}
|
106
125
|
rb_funcall2(self, rb_intern("autoproxy="), 1, &autoproxy);
|
107
126
|
rb_funcall2(self, rb_intern("user_agent="), 1, &user_agent);
|
@@ -131,7 +150,7 @@ VALUE qv_handle_user_agent_set(VALUE self, VALUE val)
|
|
131
150
|
typedef struct qv_supports_params_st
|
132
151
|
{
|
133
152
|
qv_handle_t *handle;
|
134
|
-
|
153
|
+
char *url;
|
135
154
|
QuviSupportsType type;
|
136
155
|
QuviSupportsMode mode;
|
137
156
|
QuviBoolean res;
|
@@ -140,22 +159,23 @@ typedef struct qv_supports_params_st
|
|
140
159
|
static void* qv_handle_supports_p_nogvl(void *data1)
|
141
160
|
{
|
142
161
|
qv_supports_params_t *params = data1;
|
143
|
-
params->res = quvi_supports(params->handle->q,
|
162
|
+
params->res = quvi_supports(params->handle->q, params->url,
|
144
163
|
params->mode, params->type);
|
145
164
|
return 0;
|
146
165
|
}
|
147
166
|
|
148
167
|
VALUE qv_handle_supports_p(int argc, VALUE *argv, VALUE self)
|
149
168
|
{
|
150
|
-
VALUE opts;
|
169
|
+
VALUE opts, url;
|
151
170
|
qv_supports_params_t params;
|
152
171
|
|
172
|
+
rb_scan_args(argc, argv, "11", &url, &opts);
|
173
|
+
|
153
174
|
params.handle = DATA_PTR(self);
|
154
175
|
params.type = QUVI_SUPPORTS_TYPE_ANY;
|
155
176
|
params.mode = QUVI_SUPPORTS_MODE_OFFLINE;
|
156
177
|
params.res = QUVI_FALSE;
|
157
|
-
|
158
|
-
Check_Type(params.url, T_STRING);
|
178
|
+
params.url = StringValueCStr(url);
|
159
179
|
if (opts != Qnil) {
|
160
180
|
VALUE arg;
|
161
181
|
Check_Type(opts, T_HASH);
|
@@ -174,7 +194,7 @@ VALUE qv_handle_supports_p(int argc, VALUE *argv, VALUE self)
|
|
174
194
|
} else if (arg == qv_sym_any) {
|
175
195
|
params.type = QUVI_SUPPORTS_TYPE_ANY;
|
176
196
|
} else {
|
177
|
-
rb_raise(rb_eArgError, "unknown type: %s",
|
197
|
+
rb_raise(rb_eArgError, "unknown type: %s", StringValueCStr(arg));
|
178
198
|
}
|
179
199
|
}
|
180
200
|
}
|
@@ -182,12 +202,184 @@ VALUE qv_handle_supports_p(int argc, VALUE *argv, VALUE self)
|
|
182
202
|
if (params.res == QUVI_TRUE) {
|
183
203
|
return Qtrue;
|
184
204
|
}
|
185
|
-
if (quvi_errcode(params.handle) != QUVI_ERROR_NO_SUPPORT) {
|
186
|
-
qv_raise(params.handle, "unable to check if URL supported");
|
205
|
+
if (quvi_errcode(params.handle->q) != QUVI_ERROR_NO_SUPPORT) {
|
206
|
+
qv_raise(params.handle, rb_sprintf("unable to check if URL supported (url=%s)", params.url));
|
187
207
|
}
|
188
208
|
return Qfalse;
|
189
209
|
}
|
190
210
|
|
211
|
+
VALUE qv_handle_each_script(VALUE self)
|
212
|
+
{
|
213
|
+
qv_handle_t *handle = DATA_PTR(self);
|
214
|
+
QuviScriptType types[] = {
|
215
|
+
QUVI_SCRIPT_TYPE_SCAN,
|
216
|
+
QUVI_SCRIPT_TYPE_PLAYLIST,
|
217
|
+
QUVI_SCRIPT_TYPE_MEDIA,
|
218
|
+
QUVI_SCRIPT_TYPE_SUBTITLE,
|
219
|
+
QUVI_SCRIPT_TYPE_SUBTITLE_EXPORT
|
220
|
+
};
|
221
|
+
VALUE type_names[] = {
|
222
|
+
rb_str_freeze(rb_external_str_new_cstr("scan")),
|
223
|
+
rb_str_freeze(rb_external_str_new_cstr("playlist")),
|
224
|
+
rb_str_freeze(rb_external_str_new_cstr("media")),
|
225
|
+
rb_str_freeze(rb_external_str_new_cstr("subtitle")),
|
226
|
+
rb_str_freeze(rb_external_str_new_cstr("subtitle_export"))
|
227
|
+
};
|
228
|
+
size_t i;
|
229
|
+
|
230
|
+
RETURN_ENUMERATOR(self, 0, NULL);
|
231
|
+
|
232
|
+
for (i = 0; i < sizeof(types) / sizeof(QuviScriptType); ++i) {
|
233
|
+
while (quvi_script_next(handle->q, types[i]) == QUVI_TRUE) {
|
234
|
+
VALUE script = rb_hash_new();
|
235
|
+
char *s;
|
236
|
+
|
237
|
+
#define set_property(key, id) \
|
238
|
+
s = NULL; \
|
239
|
+
quvi_script_get(handle->q, types[i], id, &s); \
|
240
|
+
if (s) { rb_hash_aset(script, key, rb_external_str_new_cstr(s)); }
|
241
|
+
set_property(qv_sym_sha1, QUVI_SCRIPT_PROPERTY_SHA1);
|
242
|
+
set_property(qv_sym_filepath, QUVI_SCRIPT_PROPERTY_FILEPATH);
|
243
|
+
rb_hash_aset(script, qv_sym_type, type_names[i]);
|
244
|
+
quvi_script_get(handle->q, types[i], QUVI_SCRIPT_PROPERTY_DOMAINS, &s);
|
245
|
+
if (strlen(s) > 0) {
|
246
|
+
VALUE domains = rb_external_str_new_cstr(s);
|
247
|
+
rb_hash_aset(script, qv_sym_domains, rb_str_split(domains, ","));
|
248
|
+
}
|
249
|
+
set_property(qv_sym_export_format, QUVI_SCRIPT_PROPERTY_EXPORT_FORMAT);
|
250
|
+
#undef set_property
|
251
|
+
|
252
|
+
rb_yield(script);
|
253
|
+
}
|
254
|
+
}
|
255
|
+
return Qnil;
|
256
|
+
}
|
257
|
+
|
258
|
+
typedef struct qv_media_new_params_st
|
259
|
+
{
|
260
|
+
qv_handle_t *handle;
|
261
|
+
char *url;
|
262
|
+
quvi_media_t res;
|
263
|
+
} qv_media_new_params_t;
|
264
|
+
|
265
|
+
static void* qv_media_new_nogvl(void *data1)
|
266
|
+
{
|
267
|
+
qv_media_new_params_t *params = data1;
|
268
|
+
params->res = quvi_media_new(params->handle->q, params->url);
|
269
|
+
return 0;
|
270
|
+
}
|
271
|
+
|
272
|
+
VALUE qv_handle_parse_media(VALUE self, VALUE url)
|
273
|
+
{
|
274
|
+
qv_media_new_params_t params;
|
275
|
+
VALUE media, streams, stream;
|
276
|
+
double d;
|
277
|
+
char *s, *best;
|
278
|
+
|
279
|
+
params.handle = DATA_PTR(self);
|
280
|
+
params.url = StringValueCStr(url);
|
281
|
+
|
282
|
+
rb_thread_call_without_gvl(qv_media_new_nogvl, ¶ms, RUBY_UBF_IO, 0);
|
283
|
+
if (quvi_ok(params.handle->q) == QUVI_FALSE) {
|
284
|
+
qv_raise(params.handle, rb_sprintf("unable create quvi_media_t handle (url=%s)", params.url));
|
285
|
+
}
|
286
|
+
media = rb_hash_new();
|
287
|
+
#define set_property_str(item, key, id) \
|
288
|
+
s = NULL; \
|
289
|
+
quvi_media_get(params.res, id, &s); \
|
290
|
+
if (s) { rb_hash_aset(item, key, rb_external_str_new_cstr(s)); }
|
291
|
+
#define set_property_int(item, key, id) \
|
292
|
+
d = -1; \
|
293
|
+
quvi_media_get(params.res, id, &d); \
|
294
|
+
if (d > 0) { rb_hash_aset(item, key, INT2NUM((int)d)); }
|
295
|
+
set_property_str(media, qv_sym_id, QUVI_MEDIA_PROPERTY_ID);
|
296
|
+
set_property_str(media, qv_sym_title, QUVI_MEDIA_PROPERTY_TITLE);
|
297
|
+
set_property_str(media, qv_sym_thumbnail_url, QUVI_MEDIA_PROPERTY_THUMBNAIL_URL);
|
298
|
+
set_property_int(media, qv_sym_start_time_ms, QUVI_MEDIA_PROPERTY_START_TIME_MS);
|
299
|
+
set_property_int(media, qv_sym_duration_ms, QUVI_MEDIA_PROPERTY_DURATION_MS);
|
300
|
+
streams = rb_hash_aset(media, qv_sym_streams, rb_ary_new());
|
301
|
+
quvi_media_stream_choose_best(params.res);
|
302
|
+
quvi_media_get(params.res, QUVI_MEDIA_STREAM_PROPERTY_ID, &best);
|
303
|
+
quvi_media_stream_reset(params.res);
|
304
|
+
while (quvi_media_stream_next(params.res) == QUVI_TRUE) {
|
305
|
+
stream = rb_hash_new();
|
306
|
+
set_property_str(stream, qv_sym_id, QUVI_MEDIA_STREAM_PROPERTY_ID);
|
307
|
+
if (strcmp(best, s) == 0) {
|
308
|
+
rb_hash_aset(stream, qv_sym_best, Qtrue);
|
309
|
+
}
|
310
|
+
set_property_int(stream, qv_sym_video_height, QUVI_MEDIA_STREAM_PROPERTY_VIDEO_HEIGHT);
|
311
|
+
set_property_int(stream, qv_sym_video_width, QUVI_MEDIA_STREAM_PROPERTY_VIDEO_WIDTH);
|
312
|
+
set_property_str(stream, qv_sym_video_encoding, QUVI_MEDIA_STREAM_PROPERTY_VIDEO_ENCODING);
|
313
|
+
set_property_int(stream, qv_sym_video_bitrate_kbit_s, QUVI_MEDIA_STREAM_PROPERTY_VIDEO_BITRATE_KBIT_S);
|
314
|
+
set_property_str(stream, qv_sym_audio_encoding, QUVI_MEDIA_STREAM_PROPERTY_AUDIO_ENCODING);
|
315
|
+
set_property_int(stream, qv_sym_audio_bitrate_kbit_s, QUVI_MEDIA_STREAM_PROPERTY_AUDIO_BITRATE_KBIT_S);
|
316
|
+
set_property_str(stream, qv_sym_container, QUVI_MEDIA_STREAM_PROPERTY_CONTAINER);
|
317
|
+
set_property_str(stream, qv_sym_url, QUVI_MEDIA_STREAM_PROPERTY_URL);
|
318
|
+
rb_ary_push(streams, stream);
|
319
|
+
}
|
320
|
+
|
321
|
+
#undef set_property_str
|
322
|
+
#undef set_property_int
|
323
|
+
quvi_media_free(params.res);
|
324
|
+
|
325
|
+
return media;
|
326
|
+
}
|
327
|
+
|
328
|
+
typedef struct qv_playlist_new_params_st
|
329
|
+
{
|
330
|
+
qv_handle_t *handle;
|
331
|
+
char *url;
|
332
|
+
quvi_playlist_t res;
|
333
|
+
} qv_playlist_new_params_t;
|
334
|
+
|
335
|
+
static void* qv_playlist_new_nogvl(void *data1)
|
336
|
+
{
|
337
|
+
qv_media_new_params_t *params = data1;
|
338
|
+
params->res = quvi_playlist_new(params->handle->q, params->url);
|
339
|
+
return 0;
|
340
|
+
}
|
341
|
+
|
342
|
+
VALUE qv_handle_parse_playlist(VALUE self, VALUE url)
|
343
|
+
{
|
344
|
+
qv_playlist_new_params_t params;
|
345
|
+
VALUE playlist, media, medium;
|
346
|
+
char *s;
|
347
|
+
double d;
|
348
|
+
|
349
|
+
params.handle = DATA_PTR(self);
|
350
|
+
params.url = StringValueCStr(url);
|
351
|
+
rb_thread_call_without_gvl(qv_playlist_new_nogvl, ¶ms, RUBY_UBF_IO, 0);
|
352
|
+
if (quvi_ok(params.handle->q) == QUVI_FALSE) {
|
353
|
+
qv_raise(params.handle, rb_sprintf("unable create quvi_media_t handle (url=%s)", params.url));
|
354
|
+
}
|
355
|
+
playlist = rb_hash_new();
|
356
|
+
#define set_property_str(item, key, id) \
|
357
|
+
s = NULL; \
|
358
|
+
quvi_playlist_get(params.res, id, &s); \
|
359
|
+
if (s) { rb_hash_aset(item, key, rb_external_str_new_cstr(s)); }
|
360
|
+
#define set_property_int(item, key, id) \
|
361
|
+
d = -1; \
|
362
|
+
quvi_playlist_get(params.res, id, &d); \
|
363
|
+
if (d > 0) { rb_hash_aset(item, key, INT2NUM((int)d)); }
|
364
|
+
|
365
|
+
set_property_str(playlist, qv_sym_id, QUVI_PLAYLIST_PROPERTY_ID);
|
366
|
+
set_property_str(playlist, qv_sym_title, QUVI_PLAYLIST_PROPERTY_TITLE);
|
367
|
+
set_property_str(playlist, qv_sym_thumbnail_url, QUVI_PLAYLIST_PROPERTY_THUMBNAIL_URL);
|
368
|
+
media = rb_hash_aset(playlist, qv_sym_media, rb_ary_new());
|
369
|
+
while (quvi_playlist_media_next(params.res) == QUVI_TRUE) {
|
370
|
+
medium = rb_hash_new();
|
371
|
+
set_property_str(medium, qv_sym_url, QUVI_PLAYLIST_MEDIA_PROPERTY_URL);
|
372
|
+
set_property_str(medium, qv_sym_title, QUVI_PLAYLIST_MEDIA_PROPERTY_TITLE);
|
373
|
+
set_property_int(medium, qv_sym_duration_ms, QUVI_PLAYLIST_MEDIA_PROPERTY_DURATION_MS);
|
374
|
+
rb_ary_push(media, medium);
|
375
|
+
}
|
376
|
+
#undef set_property_str
|
377
|
+
#undef set_property_int
|
378
|
+
|
379
|
+
quvi_playlist_free(params.res);
|
380
|
+
return playlist;
|
381
|
+
}
|
382
|
+
|
191
383
|
void init_quvi_handle()
|
192
384
|
{
|
193
385
|
qv_cHandle = rb_define_class_under(qv_mQuvi, "Handle", rb_cObject);
|
@@ -196,6 +388,9 @@ void init_quvi_handle()
|
|
196
388
|
rb_define_method(qv_cHandle, "supports?", qv_handle_supports_p, -1);
|
197
389
|
rb_define_method(qv_cHandle, "autoproxy=", qv_handle_autoproxy_set, 1);
|
198
390
|
rb_define_method(qv_cHandle, "user_agent=", qv_handle_user_agent_set, 1);
|
391
|
+
rb_define_method(qv_cHandle, "each_script", qv_handle_each_script, 0);
|
392
|
+
rb_define_method(qv_cHandle, "parse_media", qv_handle_parse_media, 1);
|
393
|
+
rb_define_method(qv_cHandle, "parse_playlist", qv_handle_parse_playlist, 1);
|
199
394
|
|
200
395
|
qv_DEFAULT_USER_AGENT = rb_const_get(qv_cHandle, rb_intern("DEFAULT_USER_AGENT"));
|
201
396
|
}
|
@@ -210,6 +405,25 @@ void init_symbols()
|
|
210
405
|
qv_sym_subtitle = ID2SYM(rb_intern("subtitle"));
|
211
406
|
qv_sym_type = ID2SYM(rb_intern("type"));
|
212
407
|
qv_sym_user_agent = ID2SYM(rb_intern("user_agent"));
|
408
|
+
qv_sym_export_format = ID2SYM(rb_intern("export_format"));
|
409
|
+
qv_sym_filepath = ID2SYM(rb_intern("filepath"));
|
410
|
+
qv_sym_domains = ID2SYM(rb_intern("domains"));
|
411
|
+
qv_sym_sha1 = ID2SYM(rb_intern("sha1"));
|
412
|
+
qv_sym_title = ID2SYM(rb_intern("title"));
|
413
|
+
qv_sym_id = ID2SYM(rb_intern("id"));
|
414
|
+
qv_sym_thumbnail_url = ID2SYM(rb_intern("thumbnail_url"));
|
415
|
+
qv_sym_start_time_ms = ID2SYM(rb_intern("start_time_ms"));
|
416
|
+
qv_sym_duration_ms = ID2SYM(rb_intern("duration_ms"));
|
417
|
+
qv_sym_video_height = ID2SYM(rb_intern("video_height"));
|
418
|
+
qv_sym_video_width = ID2SYM(rb_intern("video_width"));
|
419
|
+
qv_sym_video_encoding = ID2SYM(rb_intern("video_encoding"));
|
420
|
+
qv_sym_video_bitrate_kbit_s = ID2SYM(rb_intern("video_bitrate_kbit_s"));
|
421
|
+
qv_sym_audio_encoding = ID2SYM(rb_intern("audio_encoding"));
|
422
|
+
qv_sym_audio_bitrate_kbit_s = ID2SYM(rb_intern("audio_bitrate_kbit_s"));
|
423
|
+
qv_sym_container = ID2SYM(rb_intern("container"));
|
424
|
+
qv_sym_url = ID2SYM(rb_intern("url"));
|
425
|
+
qv_sym_streams = ID2SYM(rb_intern("streams"));
|
426
|
+
qv_sym_best = ID2SYM(rb_intern("best"));
|
213
427
|
}
|
214
428
|
|
215
429
|
void Init_quvi_ext()
|
data/lib/quvi.rb
CHANGED
@@ -2,3 +2,61 @@ require "quvi/version"
|
|
2
2
|
require "quvi/error"
|
3
3
|
require "quvi/handle"
|
4
4
|
require "quvi_ext"
|
5
|
+
|
6
|
+
require 'thread'
|
7
|
+
require 'monitor'
|
8
|
+
|
9
|
+
module Quvi
|
10
|
+
def self.parse(*urls)
|
11
|
+
options = urls.last.is_a?(Hash) ? urls.pop : {}
|
12
|
+
res = parse_multiple(urls, options)
|
13
|
+
urls.size == 1 ? res.first : res
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.parse_multiple(urls, options = {})
|
17
|
+
return [] if urls.empty?
|
18
|
+
num_threads = options.fetch(:threads) { 2 }
|
19
|
+
num_threads = [num_threads, urls.size].min
|
20
|
+
tasks = Queue.new
|
21
|
+
tasks.extend(MonitorMixin)
|
22
|
+
urls.each do |url|
|
23
|
+
tasks.push([:media, url])
|
24
|
+
tasks.push([:playlist, url])
|
25
|
+
end
|
26
|
+
tasks_tbd = tasks.size
|
27
|
+
done = tasks.new_cond
|
28
|
+
results = Queue.new
|
29
|
+
threads = Array.new(num_threads) do
|
30
|
+
Thread.new do
|
31
|
+
handle = Quvi::Handle.new(options)
|
32
|
+
loop do
|
33
|
+
type, url = tasks.pop
|
34
|
+
begin
|
35
|
+
if res = handle.parse(url, options.merge(:type => type))
|
36
|
+
results.push([url, res])
|
37
|
+
end
|
38
|
+
rescue Quvi::Error => ex
|
39
|
+
results.push([url, ex])
|
40
|
+
ensure
|
41
|
+
tasks.synchronize do
|
42
|
+
tasks_tbd -= 1
|
43
|
+
done.signal
|
44
|
+
break if tasks_tbd <= 0
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
tasks.synchronize do
|
51
|
+
done.wait_while do
|
52
|
+
tasks_tbd > 0
|
53
|
+
end
|
54
|
+
end if tasks_tbd > 0
|
55
|
+
res = []
|
56
|
+
until results.empty?
|
57
|
+
u, r = results.pop
|
58
|
+
res[urls.index(u)] = r
|
59
|
+
end
|
60
|
+
res
|
61
|
+
end
|
62
|
+
end
|
data/lib/quvi/handle.rb
CHANGED
@@ -2,6 +2,16 @@ module Quvi
|
|
2
2
|
class Handle
|
3
3
|
DEFAULT_USER_AGENT = "Mozilla/5.0".freeze
|
4
4
|
|
5
|
-
attr_accessor :user_agent, :allow_cookies
|
5
|
+
attr_accessor :user_agent, :allow_cookies
|
6
|
+
|
7
|
+
def parse(url, options = {})
|
8
|
+
online = options.fetch(:online) { true }
|
9
|
+
type = options.fetch(:type) { true }
|
10
|
+
if supports?(url, :type => type, :online => online)
|
11
|
+
res = send("parse_#{type}", url)
|
12
|
+
res[:type] = type
|
13
|
+
res
|
14
|
+
end
|
15
|
+
end
|
6
16
|
end
|
7
|
-
end
|
17
|
+
end
|
data/lib/quvi/version.rb
CHANGED
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: quvi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sergey Avseyev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-03-
|
11
|
+
date: 2014-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - ~>
|
17
|
+
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '1.5'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - ~>
|
24
|
+
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '1.5'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rake
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
description: This is the wrapper for libquvi library, which allows to extract media
|
@@ -47,7 +47,7 @@ extensions:
|
|
47
47
|
- ext/quvi_ext/extconf.rb
|
48
48
|
extra_rdoc_files: []
|
49
49
|
files:
|
50
|
-
- .gitignore
|
50
|
+
- ".gitignore"
|
51
51
|
- Gemfile
|
52
52
|
- Guardfile
|
53
53
|
- LICENSE
|
@@ -72,17 +72,17 @@ require_paths:
|
|
72
72
|
- lib
|
73
73
|
required_ruby_version: !ruby/object:Gem::Requirement
|
74
74
|
requirements:
|
75
|
-
- -
|
75
|
+
- - ">="
|
76
76
|
- !ruby/object:Gem::Version
|
77
77
|
version: '0'
|
78
78
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
requirements: []
|
84
84
|
rubyforge_project:
|
85
|
-
rubygems_version: 2.
|
85
|
+
rubygems_version: 2.2.2
|
86
86
|
signing_key:
|
87
87
|
specification_version: 4
|
88
88
|
summary: The library to parse the media stream properties.
|