youtube.js: fix scraping bug in obtaining video key
[conkeror.git] / modules / page-modes / youtube.js
blob0d55e3603de76d4fe555e4f7125972d8dcc0c80c
1 /**
2  * (C) Copyright 2008 Jeremy Maitin-Shepard
3  *
4  * Use, modification, and distribution are subject to the terms specified in the
5  * COPYING file.
6 **/
8 require("content-buffer.js");
9 require("media.js");
11 let media_youtube_content_key_regexp = /"t": "([^"]+)"/;
12 let media_youtube_content_title_regexp = new RegExp("&title=([^\"'&]+)");
14 function media_scrape_youtube_document_text(source_frame, code, text, results) {
16     var title_match = media_youtube_content_title_regexp.exec(text);
17     var title = null;
18     if (!title_match)
19         return;
21     let res = media_youtube_content_key_regexp.exec(text);
22     if (!res)
23         return;
24     results.push(load_spec({uri: 'http://youtube.com/get_video?video_id=' + code + '&' + res[1],
25                             suggest_filename_from_uri: false,
26                             title: decodeURIComponent(title_match[1]),
27                             filename_extension: "flv",
28                             source_frame: buffer.top_frame,
29                             mime_type: "video/x-flv"}));
32 function media_scrape_youtube(buffer, results) {
33     try {
34         var uri = buffer.current_URI.spec;
36         var result = media_youtube_uri_test_regexp.exec(uri);
38         if (!result)
39             return;
41         let text = buffer.document.documentElement.innerHTML;
42         let code = result[1];
44         media_scrape_youtube_document_text(buffer.top_frame, code, text, results);
45     } catch (e if !(e instanceof interactive_error)) {}
48 define_page_mode("youtube_mode", "YouTube", $enable = function (buffer) {
49     buffer.local_variables.media_scrapers = [media_scrape_youtube];
50     media_setup_local_object_classes(buffer);
51 });
53 function media_scrape_embedded_youtube(buffer, results) {
55     const embedded_youtube_regexp = /^http:\/\/[a-zA-Z0-9\-.]+\.youtube\.com\/v\/(.*)$/;
57     for (let frame in frame_iterator(buffer.top_frame, buffer.focused_frame)) {
58         // Look for embedded YouTube videos
59         let obj_els = frame.document.getElementsByTagName("object");
60         for (let i = 0; i < obj_els.length; ++i) {
61             let obj_el = obj_els[i];
62             let param_els = obj_el.getElementsByTagName("param");
63             inner:
64             for (let j = 0; j < param_els.length; ++j) {
65                 let param_el = param_els[j];
66                 let match;
67                 if (param_el.getAttribute("name").toLowerCase() == "movie" &&
68                     (match = embedded_youtube_regexp.exec(param_el.getAttribute("value"))) != null) {
70                     try {
71                         let code = match[1];
72                         let lspec = load_spec({uri: "http://youtube.com/watch?v=" + code});
73                         var result =
74                             yield buffer.window.minibuffer.wait_for(
75                                 "Requesting " + lspec.uri + "...",
76                                 send_http_request(lspec));
77                         let text = result.responseText;
78                         if (text != null && text.length > 0)
79                             media_scrape_youtube_document_text(frame, code, text, results);
80                     } catch (e if (e instanceof abort)) {
81                         // Still allow other media scrapers to try even if the user aborted an http request,
82                         // but don't continue looking for embedded youtube videos.
83                         return;
84                     } catch (e) {
85                         // Some other error here means there was some problem with the request.
86                         // We'll just ignore it.
87                     }
88                     break inner;
89                 }
90             }
91         }
92     }
96 // Use the embedded youtube scraper by default
97 media_scrapers.unshift(media_scrape_embedded_youtube);
99 let media_youtube_uri_test_regexp = build_url_regex($domain = /(?:[a-z]+\.)?youtube/,
100                                                     $path = /watch\?v=([A-Za-z0-9\-_]+)/);
101 auto_mode_list.push([media_youtube_uri_test_regexp, youtube_mode]);