1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224 | #
# encoding: UTF-8
# api: streamtuner2
# type: functions
# title: http download / methods
# description: http utility
# version: 1.3
#
# Provides a http GET method with gtk.statusbar() callback.
# And a function to add trailings slashes on http URLs.
#
# The latter code is pretty much unreadable. But let's put the
# blame on urllib2, the most braindamaged code in the Python
# standard library.
#
try:
import urllib2
from urllib import urlencode
except:
import urllib.request as urllib2
import urllib.parse.urlencode as urlencode
import config
from config import __print__, dbg
#-- url download ---------------------------------------------
#-- chains to progress meter and status bar in main window
feedback = None
# sets either text or percentage, so may take two parameters
def progress_feedback(*args):
# use reset values if none given
if not args:
args = ["", 1.0]
# send to main win
if feedback:
try: [feedback(d) for d in args]
except: pass
#-- GET
def get(url, maxsize=1<<19, feedback="old"):
__print__("GET", url)
# statusbar info
progress_feedback(url, 0.0)
# read
content = ""
f = urllib2.urlopen(url)
max = 222000 # mostly it's 200K, but we don't get any real information
read_size = 1
# multiple steps
while (read_size and len(content) < maxsize):
# partial read
add = f.read(8192)
content = content + add
read_size = len(add)
# set progress meter
progress_feedback(float(len(content)) / float(max))
# done
# clean statusbar
progress_feedback()
# fin
__print__(len(content))
return content
#-- fix invalid URLs
def fix_url(url):
if url is None:
url = ""
if len(url):
# remove whitespace
url = url.strip()
# add scheme
if (url.find("://") < 0):
url = "http://" + url
# add mandatory path
if (url.find("/", 10) < 0):
url = url + "/"
return url
# default HTTP headers for AJAX/POST request
default_headers = {
"User-Agent": "streamtuner2/2.1 (X11; U; Linux AMD64; en; rv:1.5.0.1) like WinAmp/2.1 but not like Googlebot/2.1", #"Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6",
"Accept": "*/*;q=0.5, audio/*, url/*",
"Accept-Language": "en-US,en,de,es,fr,it,*;q=0.1",
"Accept-Encoding": "gzip,deflate",
"Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.1",
"Keep-Alive": "115",
"Connection": "keep-alive",
#"Content-Length", "56",
#"Cookie": "s_pers=%20s_getnr%3D1278607170446-Repeat%7C1341679170446%3B%20s_nrgvo%3DRepeat%7C1341679170447%3B; s_sess=%20s_cc%3Dtrue%3B%20s_sq%3Daolshtcst%252Caolsvc%253D%252526pid%25253Dsht%25252520%2525253A%25252520SHOUTcast%25252520Radio%25252520%2525257C%25252520Search%25252520Results%252526pidt%25253D1%252526oid%25253Dfunctiononclick%25252528event%25252529%2525257BshowMoreGenre%25252528%25252529%2525253B%2525257D%252526oidt%25253D2%252526ot%25253DDIV%3B; aolDemoChecked=1.849061",
"Pragma": "no-cache",
"Cache-Control": "no-cache",
}
# simulate ajax calls
def ajax(url, post, referer=""):
# request
headers = default_headers
headers.update({
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"X-Requested-With": "XMLHttpRequest",
"Referer": (referer if referer else url),
})
if type(post) == dict:
post = urlencode(post)
request = urllib2.Request(url, post, headers)
# open url
__print__( vars(request) )
progress_feedback(url, 0.2)
r = urllib2.urlopen(request)
# get data
__print__( r.info() )
progress_feedback(0.5)
data = r.read()
progress_feedback()
return data
# http://techknack.net/python-urllib2-handlers/
from gzip import GzipFile
from StringIO import StringIO
class ContentEncodingProcessor(urllib2.BaseHandler):
"""A handler to add gzip capabilities to urllib2 requests """
# add headers to requests
def http_request(self, req):
req.add_header("Accept-Encoding", "gzip, deflate")
return req
# decode
def http_response(self, req, resp):
old_resp = resp
# gzip
if resp.headers.get("content-encoding") == "gzip":
gz = GzipFile(
fileobj=StringIO(resp.read()),
mode="r"
)
resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code)
resp.msg = old_resp.msg
# deflate
if resp.headers.get("content-encoding") == "deflate":
gz = StringIO( deflate(resp.read()) )
resp = urllib2.addinfourl(gz, old_resp.headers, old_resp.url, old_resp.code) # 'class to add info() and geturl() methods to an open file.'
resp.msg = old_resp.msg
return resp
# deflate support
import zlib
def deflate(data): # zlib only provides the zlib compress format, not the deflate format;
try: # so on top of all there's this workaround:
return zlib.decompress(data, -zlib.MAX_WBITS)
except zlib.error:
return zlib.decompress(data)
#-- init for later use
if urllib2:
# config 1
handlers = [None, None, None]
# base
handlers[0] = urllib2.HTTPHandler()
if config.conf.debug:
handlers[0].set_http_debuglevel(3)
# content-encoding
handlers[1] = ContentEncodingProcessor()
# store cookies at runtime
import cookielib
cj = cookielib.CookieJar()
handlers[2] = urllib2.HTTPCookieProcessor( cj )
# inject into urllib2
urllib2.install_opener( urllib2.build_opener(*handlers) )
# alternative function names
AJAX=ajax
POST=ajax
GET=get
URL=fix_url
|
|
<
<
<
|
|
|
<
<
<
<
|
|
|
|
<
<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
<
<
|
>
>
|
|
|
>
|
|
|
|
<
|
|
<
<
>
>
>
>
>
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
< | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
| #
# encoding: UTF-8
# api: streamtuner2
# type: functions
# title: http download / methods
# description: http utility
# version: 1.4
#
# Provides a http GET method with gtk.statusbar() callback.
# And a function to add trailings slashes on http URLs.
#
#
from compat2and3 import urllib2, urlencode, urlparse, cookielib, StringIO, xrange, PY3
from gzip import GzipFile
from config import conf, __print__, dbg
import requests
import copy
#-- chains to progress meter and status bar in main window
feedback = None
# sets either text or percentage, so may take two parameters
def progress_feedback(*args):
# use reset values if none given
if not args:
args = ["", 1.0]
# send to main win
if feedback:
try: [feedback(d) for d in args]
except: pass
# default HTTP headers for AJAX/POST request
default_headers = {
"User-Agent": "streamtuner2/2.1 (X11; U; Linux AMD64; en; rv:1.5.0.1) like WinAmp/2.1 but not like Googlebot/2.1", #"Mozilla/5.0 (X11; U; Linux x86_64; de; rv:1.9.2.6) Gecko/20100628 Ubuntu/10.04 (lucid) Firefox/3.6.6",
"Accept": "*/*;q=0.5, audio/*, url/*",
"Accept-Language": "en-US,en,de,es,fr,it,*;q=0.1",
"Accept-Encoding": "gzip,deflate",
"Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.1",
"Keep-Alive": "115",
"Connection": "keep-alive",
"Pragma": "no-cache",
"Cache-Control": "no-cache",
}
#-- GET
def get(url, params={}, referer="", post=0, ajax=0, binary=0):
__print__( dbg.HTTP, "GET", url)
# statusbar info
progress_feedback(url, 0.1)
# combine headers
headers = copy.copy(default_headers)
if ajax:
headers["X-Requested-With"] = "XMLHttpRequest"
if referer:
headers["Referer"] = (referer if referer else url)
# read
if post:
__print__("POST")
r = requests.post(url, params=params, headers=headers)
else:
__print__("GET")
r = requests.get(url, params=params, headers=headers)
# result
progress_feedback(0.9)
content = (r.content if binary else r.text)
# finish, clean statusbar
progress_feedback()
__print__( dbg.INFO, "Content-Length", len(content) )
return content
# simulate ajax calls
def ajax(url, params, referer="", binary=0):
get(url, params, referer, binary, ajax=1)
#-- fix invalid URLs
def fix_url(url):
if url is None:
url = ""
if len(url):
# remove whitespace
url = url.strip()
# add scheme
if (url.find("://") < 0):
url = "http://" + url
# add mandatory path
if (url.find("/", 10) < 0):
url = url + "/"
return url
|