2 -- Copyright (C) 2012-2013 Toni Gundogdu <legatvs@gmail.com>
4 -- This file is part of libquvi-scripts <http://quvi.sourceforge.net/>.
6 -- This program is free software: you can redistribute it and/or
7 -- modify it under the terms of the GNU Affero General Public
8 -- License as published by the Free Software Foundation, either
9 -- version 3 of the License, or (at your option) any later version.
11 -- This program is distributed in the hope that it will be useful,
12 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
13 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 -- GNU Affero General Public License for more details.
16 -- You should have received a copy of the GNU Affero General
17 -- Public License along with this program. If not, see
18 -- <http://www.gnu.org/licenses/>.
24 Return the `ident' data for the {media,subtitle} scripts.
28 A table containing the values expected by the library.
30 function M
.ident(qargs
)
31 local u
= M
.normalize(qargs
.input_url
)
33 domains
= table.concat({'youtube.com'}, ','),
34 can_parse_url
= M
.can_parse_url(u
)
39 Check if script can parse the URL.
45 function M
.can_parse_url(url
)
46 local U
= require
'socket.url'
47 local t
= U
.parse(url
)
48 if t
and t
.scheme
and t
.scheme
:lower():match('^https?$')
49 and t
.host
and t
.host
:lower():match('youtube%.com$')
50 and t
.query
and t
.query
:lower():match('^v=[%w-_]+')
51 and t
.path
and t
.path
:lower():match('^/watch$')
60 "Normalize" URL to YouTube media URL. See the test URLs for examples.
66 function M
.normalize(url
)
67 -- Leave if url is undefined for some reason.
71 local U
= require
'socket.url'
72 local u
= U
.parse(url
)
73 -- Leave if parsing fails for some reason.
74 if not u
.host
or not u
.path
then
78 u
.host
= u
.host
:gsub('youtu%.be', 'youtube.com')
79 -- Try to lookup the video/media ID.
80 for _
,p
in pairs({'/embed/([-_%w]+)', '/%w/([-_%w]+)', '/([-_%w]+)'}) do
81 local v_id
= u
.path
:match(p
)
82 if v_id
and #v_id
==11 then -- Convert the URL into a YouTube media URL.
83 u
.query
= table.concat({'v=',v_id
})
87 return U
.build(u
) -- Rebuild and return the media URL.
91 Append URL to qargs.media_url if it is unique by comparing video IDs.
95 function M
.append_if_unique(qargs
, url
)
96 if not url
then return end
98 url
= M
.normalize(url
)
100 local U
= require
'socket.url'
101 local t
= U
.parse(url
)
103 if not t
.host
or not t
.query
then return end
105 local p
= 'v=([%w-_]+)'
106 local v
= t
.query
:match(p
)
108 for _
,u
in pairs(qargs
.media_url
) do
109 local tt
= U
.parse(u
)
110 if tt
.query
and v
== tt
.query
:match(p
) then
111 return -- Found duplicate. Ignore URL.
115 table.insert(qargs
.media_url
, url
)
123 local function test_normalize()
125 {url = 'http://youtu.be/3WSQH__H1XE',
126 expect = 'http://youtube.com/watch?v=3WSQH__H1XE'},
127 {url = 'https://youtu.be/3WSQH__H1XE',
128 expect = 'https://youtube.com/watch?v=3WSQH__H1XE'},
129 {url='http://youtu.be/v/3WSQH__H1XE?hl=en',
130 expect='http://youtube.com/watch?v=3WSQH__H1XE'},
131 {url='http://youtu.be/watch?v=3WSQH__H1XE',
132 expect='http://youtube.com/watch?v=3WSQH__H1XE'},
133 {url='http://youtu.be/embed/3WSQH__H1XE',
134 expect='http://youtube.com/watch?v=3WSQH__H1XE'},
135 {url='http://youtu.be/v/3WSQH__H1XE',
136 expect='http://youtube.com/watch?v=3WSQH__H1XE'},
137 {url='http://youtu.be/e/3WSQH__H1XE',
138 expect='http://youtube.com/watch?v=3WSQH__H1XE'},
139 {url='http://youtube.com/watch?v=3WSQH__H1XE',
140 expect='http://youtube.com/watch?v=3WSQH__H1XE'},
141 {url='http://youtube.com/embed/3WSQH__H1XE',
142 expect='http://youtube.com/watch?v=3WSQH__H1XE'},
143 {url='http://jp.youtube.com/watch?v=3WSQH__H1XE',
144 expect='http://jp.youtube.com/watch?v=3WSQH__H1XE'},
145 {url='http://jp.youtube.com/embed/3WSQH__H1XE',
146 expect='http://jp.youtube.com/watch?v=3WSQH__H1XE'},
147 {url='https://jp.youtube.com/embed/3WSQH__H1XE',
148 expect='https://jp.youtube.com/watch?v=3WSQH__H1XE'},
149 {url='http://youtube.com/3WSQH__H1XE', -- invalid page url
150 expect='http://youtube.com/watch?v=3WSQH__H1XE'}
153 for _,v in pairs(test_cases) do
154 local r = M.normalize(v.url)
155 if r ~= v.expect then
156 print(string.format('input: %s (#%s)\nexpected: %s\ngot: %s',
157 v.url, i, v.expect, r))
162 print((e==0) and 'tests OK' or error('failed tests: '..e))
170 -- vim: set ts=2 sw=2 tw=72 expandtab: