soundcloud.lua: Improve URL probe function
[vlc.git] / share / lua / playlist / soundcloud.lua
1 --[[
2  $Id$
3
4  Copyright © 2012, 2015 the VideoLAN team
5
6  Authors: Cheng Sun <chengsun9atgmail.com>
7           Pierre Ynard
8
9  This program is free software; you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation; either version 2 of the License, or
12  (at your option) any later version.
13
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  GNU General Public License for more details.
18
19  You should have received a copy of the GNU General Public License
20  along with this program; if not, write to the Free Software
21  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 --]]
23
24 -- Probe function.
25 function probe()
26     local path = vlc.path
27     path = path:gsub("^www%.", "")
28     return ( vlc.access == "http" or vlc.access == "https" )
29         and string.match( path, "^soundcloud%.com/.+/.+" )
30 end
31
32 function fix_quotes( value )
33     if string.match( value, "^\"" ) then
34         return "" -- field was really empty string
35     end
36
37     -- TODO: handle escaped backslashes and others
38     return string.gsub( value, "\\\"", "\"" )
39 end
40
41 -- Parse function.
42 function parse()
43     while true do
44         line = vlc.readline()
45         if not line then break end
46
47         -- Parameters for API call
48         if not track then
49             track = string.match( line, "soundcloud:tracks:(%d+)" )
50         end
51
52         -- For private tracks
53         if not secret then
54             secret = string.match( line, "[\"']secret_token[\"'] *: *[\"'](.-)[\"']" )
55         end
56
57         -- Metadata
58         if not name then
59             name = string.match( line, "[\"']title[\"'] *: *\"(.-[^\\])\"" )
60             if name then
61                 name = fix_quotes( name )
62             end
63         end
64
65         if not description then
66             description = string.match( line, "[\"']artwork_url[\"'] *:.-[\"']description[\"'] *: *\"(.-[^\\])\"" )
67             if description then
68                 description = fix_quotes( description )
69             end
70         end
71
72         if not artist then
73             artist = string.match( line, "[\"']username[\"'] *: *\"(.-[^\\])\"" )
74             if artist then
75                 artist = fix_quotes( artist )
76             end
77         end
78
79         if not arturl then
80             arturl = string.match( line, "[\"']artwork_url[\"'] *: *[\"'](.-)[\"']" )
81         end
82     end
83
84     if track then
85         -- API magic
86         local client_id = "02gUJC0hH2ct1EGOcYXQIzRFU91c72Ea"
87         -- app_version is not required by the API but we send it anyway
88         -- to remain unconspicuous
89         local app_version = "a089efd"
90
91         local api = vlc.stream( vlc.access.."://api.soundcloud.com/i1/tracks/"..track.."/streams?client_id="..client_id.."&app_version="..app_version..( secret and "&secret_token="..secret or "" ) )
92
93         if api then
94             local streams = api:readline() -- data is on one line only
95             -- For now only quality available is 128 kbps (http_mp3_128_url)
96             path = string.match( streams, "[\"']http_mp3_%d+_url[\"'] *: *[\"'](.-)[\"']" )
97             if path then
98                 -- FIXME: do this properly
99                 path = string.gsub( path, "\\u0026", "&" )
100             end
101         end
102     end
103
104     if not path then
105         vlc.msg.err( "Couldn't extract soundcloud audio URL, please check for updates to this script" )
106         return { }
107     end
108
109     return { { path = path, name = name, description = description, artist = artist, arturl = arturl } }
110 end