Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
C
cpython
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
cpython
Commits
13a2c279
Commit
13a2c279
authored
Feb 10, 2000
by
Fred Drake
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Untabify to pass the -tt test.
parent
857c4c36
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
807 additions
and
807 deletions
+807
-807
Lib/httplib.py
Lib/httplib.py
+15
-15
Lib/mailbox.py
Lib/mailbox.py
+240
-240
Lib/mimetypes.py
Lib/mimetypes.py
+20
-20
Lib/rfc822.py
Lib/rfc822.py
+11
-11
Lib/shelve.py
Lib/shelve.py
+109
-109
Lib/stringold.py
Lib/stringold.py
+28
-28
Lib/urllib2.py
Lib/urllib2.py
+383
-383
Lib/whichdb.py
Lib/whichdb.py
+1
-1
No files found.
Lib/httplib.py
View file @
13a2c279
...
...
@@ -44,27 +44,27 @@ HTTPS_PORT = 443
class
FakeSocket
:
def
__init__
(
self
,
sock
,
ssl
):
self
.
__sock
=
sock
self
.
__ssl
=
ssl
return
def
makefile
(
self
,
mode
):
# hopefully, never have to write
msgbuf
=
""
while
1
:
try
:
msgbuf
=
msgbuf
+
self
.
__ssl
.
read
()
except
socket
.
sslerror
,
msg
:
break
return
StringIO
(
msgbuf
)
self
.
__sock
=
sock
self
.
__ssl
=
ssl
return
def
makefile
(
self
,
mode
):
# hopefully, never have to write
msgbuf
=
""
while
1
:
try
:
msgbuf
=
msgbuf
+
self
.
__ssl
.
read
()
except
socket
.
sslerror
,
msg
:
break
return
StringIO
(
msgbuf
)
def
send
(
self
,
stuff
,
flags
=
0
):
return
self
.
__ssl
.
write
(
stuff
)
return
self
.
__ssl
.
write
(
stuff
)
def
recv
(
self
,
len
=
1024
,
flags
=
0
):
return
self
.
__ssl
.
read
(
len
)
return
self
.
__ssl
.
read
(
len
)
def
__getattr__
(
self
,
attr
):
return
getattr
(
self
.
__sock
,
attr
)
return
getattr
(
self
.
__sock
,
attr
)
class
HTTP
:
"""This class manages a connection to an HTTP server."""
...
...
Lib/mailbox.py
View file @
13a2c279
...
...
@@ -8,269 +8,269 @@ import os
class
_Mailbox
:
def
__init__
(
self
,
fp
):
self
.
fp
=
fp
self
.
seekp
=
0
def
seek
(
self
,
pos
,
whence
=
0
):
if
whence
==
1
:
# Relative to current position
self
.
pos
=
self
.
pos
+
pos
if
whence
==
2
:
# Relative to file's end
self
.
pos
=
self
.
stop
+
pos
else
:
# Default - absolute position
self
.
pos
=
self
.
start
+
pos
def
next
(
self
):
while
1
:
self
.
fp
.
seek
(
self
.
seekp
)
try
:
self
.
_search_start
()
except
EOFError
:
self
.
seekp
=
self
.
fp
.
tell
()
return
None
start
=
self
.
fp
.
tell
()
self
.
_search_end
()
self
.
seekp
=
stop
=
self
.
fp
.
tell
()
if
start
<>
stop
:
break
return
rfc822
.
Message
(
_Subfile
(
self
.
fp
,
start
,
stop
))
def
__init__
(
self
,
fp
):
self
.
fp
=
fp
self
.
seekp
=
0
def
seek
(
self
,
pos
,
whence
=
0
):
if
whence
==
1
:
# Relative to current position
self
.
pos
=
self
.
pos
+
pos
if
whence
==
2
:
# Relative to file's end
self
.
pos
=
self
.
stop
+
pos
else
:
# Default - absolute position
self
.
pos
=
self
.
start
+
pos
def
next
(
self
):
while
1
:
self
.
fp
.
seek
(
self
.
seekp
)
try
:
self
.
_search_start
()
except
EOFError
:
self
.
seekp
=
self
.
fp
.
tell
()
return
None
start
=
self
.
fp
.
tell
()
self
.
_search_end
()
self
.
seekp
=
stop
=
self
.
fp
.
tell
()
if
start
<>
stop
:
break
return
rfc822
.
Message
(
_Subfile
(
self
.
fp
,
start
,
stop
))
class
_Subfile
:
def
__init__
(
self
,
fp
,
start
,
stop
):
self
.
fp
=
fp
self
.
start
=
start
self
.
stop
=
stop
self
.
pos
=
self
.
start
def
read
(
self
,
length
=
None
):
if
self
.
pos
>=
self
.
stop
:
return
''
remaining
=
self
.
stop
-
self
.
pos
if
length
is
None
or
length
<
0
:
length
=
remaining
elif
length
>
remaining
:
length
=
remaining
self
.
fp
.
seek
(
self
.
pos
)
data
=
self
.
fp
.
read
(
length
)
self
.
pos
=
self
.
fp
.
tell
()
return
data
def
readline
(
self
,
length
=
None
):
if
self
.
pos
>=
self
.
stop
:
return
''
if
length
is
None
:
length
=
self
.
stop
-
self
.
pos
self
.
fp
.
seek
(
self
.
pos
)
data
=
self
.
fp
.
readline
(
length
)
self
.
pos
=
self
.
fp
.
tell
()
return
data
def
__init__
(
self
,
fp
,
start
,
stop
):
self
.
fp
=
fp
self
.
start
=
start
self
.
stop
=
stop
self
.
pos
=
self
.
start
def
read
(
self
,
length
=
None
):
if
self
.
pos
>=
self
.
stop
:
return
''
remaining
=
self
.
stop
-
self
.
pos
if
length
is
None
or
length
<
0
:
length
=
remaining
elif
length
>
remaining
:
length
=
remaining
self
.
fp
.
seek
(
self
.
pos
)
data
=
self
.
fp
.
read
(
length
)
self
.
pos
=
self
.
fp
.
tell
()
return
data
def
readline
(
self
,
length
=
None
):
if
self
.
pos
>=
self
.
stop
:
return
''
if
length
is
None
:
length
=
self
.
stop
-
self
.
pos
self
.
fp
.
seek
(
self
.
pos
)
data
=
self
.
fp
.
readline
(
length
)
self
.
pos
=
self
.
fp
.
tell
()
return
data
def
readlines
(
self
,
sizehint
=
-
1
):
lines
=
[]
while
1
:
line
=
self
.
readline
()
if
not
line
:
break
lines
.
append
(
line
)
if
sizehint
>=
0
:
sizehint
=
sizehint
-
len
(
line
)
if
sizehint
<=
0
:
break
return
lines
def
tell
(
self
):
return
self
.
pos
-
self
.
start
def
seek
(
self
,
pos
,
whence
=
0
):
if
whence
==
0
:
self
.
pos
=
self
.
start
+
pos
elif
whence
==
1
:
self
.
pos
=
self
.
pos
+
pos
elif
whence
==
2
:
self
.
pos
=
self
.
stop
+
pos
def
close
(
self
):
del
self
.
fp
lines
=
[]
while
1
:
line
=
self
.
readline
()
if
not
line
:
break
lines
.
append
(
line
)
if
sizehint
>=
0
:
sizehint
=
sizehint
-
len
(
line
)
if
sizehint
<=
0
:
break
return
lines
def
tell
(
self
):
return
self
.
pos
-
self
.
start
def
seek
(
self
,
pos
,
whence
=
0
):
if
whence
==
0
:
self
.
pos
=
self
.
start
+
pos
elif
whence
==
1
:
self
.
pos
=
self
.
pos
+
pos
elif
whence
==
2
:
self
.
pos
=
self
.
stop
+
pos
def
close
(
self
):
del
self
.
fp
class
UnixMailbox
(
_Mailbox
):
def
_search_start
(
self
):
while
1
:
line
=
self
.
fp
.
readline
()
if
not
line
:
raise
EOFError
if
line
[:
5
]
==
'From '
and
self
.
_isrealfromline
(
line
):
return
def
_search_end
(
self
):
while
1
:
pos
=
self
.
fp
.
tell
()
line
=
self
.
fp
.
readline
()
if
not
line
:
return
if
line
[:
5
]
==
'From '
and
self
.
_isrealfromline
(
line
):
self
.
fp
.
seek
(
pos
)
return
# An overridable mechanism to test for From-line-ness.
# You can either specify a different regular expression
# or define a whole new _isrealfromline() method.
# Note that this only gets called for lines starting with
# the 5 characters "From ".
_fromlinepattern
=
r"From \
s*[^
\s]+\
s+
\w\
w
\w\
s+
\w\
w
\w\
s+
\d?\
d
\s+"
\
r"\
d?
\d:\
d
\d(:\
d
\d)?(\
s+[^
\s]+)?\
s+
\d\
d
\d\
d
\s*$"
_regexp
=
None
def
_isrealfromline
(
self
,
line
):
if
not
self
.
_regexp
:
import
re
self
.
_regexp
=
re
.
compile
(
self
.
_fromlinepattern
)
return
self
.
_regexp
.
match
(
line
)
def
_search_start
(
self
):
while
1
:
line
=
self
.
fp
.
readline
()
if
not
line
:
raise
EOFError
if
line
[:
5
]
==
'From '
and
self
.
_isrealfromline
(
line
):
return
def
_search_end
(
self
):
while
1
:
pos
=
self
.
fp
.
tell
()
line
=
self
.
fp
.
readline
()
if
not
line
:
return
if
line
[:
5
]
==
'From '
and
self
.
_isrealfromline
(
line
):
self
.
fp
.
seek
(
pos
)
return
# An overridable mechanism to test for From-line-ness.
# You can either specify a different regular expression
# or define a whole new _isrealfromline() method.
# Note that this only gets called for lines starting with
# the 5 characters "From ".
_fromlinepattern
=
r"From \
s*[^
\s]+\
s+
\w\
w
\w\
s+
\w\
w
\w\
s+
\d?\
d
\s+"
\
r"\
d?
\d:\
d
\d(:\
d
\d)?(\
s+[^
\s]+)?\
s+
\d\
d
\d\
d
\s*$"
_regexp
=
None
def
_isrealfromline
(
self
,
line
):
if
not
self
.
_regexp
:
import
re
self
.
_regexp
=
re
.
compile
(
self
.
_fromlinepattern
)
return
self
.
_regexp
.
match
(
line
)
class
MmdfMailbox
(
_Mailbox
):
def
_search_start
(
self
):
while
1
:
line
=
self
.
fp
.
readline
()
if
not
line
:
raise
EOFError
if
line
[:
5
]
==
'
\
001
\
001
\
001
\
001
\
n
'
:
return
def
_search_end
(
self
):
while
1
:
pos
=
self
.
fp
.
tell
()
line
=
self
.
fp
.
readline
()
if
not
line
:
return
if
line
==
'
\
001
\
001
\
001
\
001
\
n
'
:
self
.
fp
.
seek
(
pos
)
return
def
_search_start
(
self
):
while
1
:
line
=
self
.
fp
.
readline
()
if
not
line
:
raise
EOFError
if
line
[:
5
]
==
'
\
001
\
001
\
001
\
001
\
n
'
:
return
def
_search_end
(
self
):
while
1
:
pos
=
self
.
fp
.
tell
()
line
=
self
.
fp
.
readline
()
if
not
line
:
return
if
line
==
'
\
001
\
001
\
001
\
001
\
n
'
:
self
.
fp
.
seek
(
pos
)
return
class
MHMailbox
:
def
__init__
(
self
,
dirname
):
import
re
pat
=
re
.
compile
(
'^[0-9][0-9]*$'
)
self
.
dirname
=
dirname
files
=
os
.
listdir
(
self
.
dirname
)
self
.
boxes
=
[]
for
f
in
files
:
if
pat
.
match
(
f
):
self
.
boxes
.
append
(
f
)
def
next
(
self
):
if
not
self
.
boxes
:
return
None
fn
=
self
.
boxes
[
0
]
del
self
.
boxes
[
0
]
fp
=
open
(
os
.
path
.
join
(
self
.
dirname
,
fn
))
return
rfc822
.
Message
(
fp
)
def
__init__
(
self
,
dirname
):
import
re
pat
=
re
.
compile
(
'^[0-9][0-9]*$'
)
self
.
dirname
=
dirname
files
=
os
.
listdir
(
self
.
dirname
)
self
.
boxes
=
[]
for
f
in
files
:
if
pat
.
match
(
f
):
self
.
boxes
.
append
(
f
)
def
next
(
self
):
if
not
self
.
boxes
:
return
None
fn
=
self
.
boxes
[
0
]
del
self
.
boxes
[
0
]
fp
=
open
(
os
.
path
.
join
(
self
.
dirname
,
fn
))
return
rfc822
.
Message
(
fp
)
class
Maildir
:
# Qmail directory mailbox
def
__init__
(
self
,
dirname
):
import
string
self
.
dirname
=
dirname
self
.
boxes
=
[]
# check for new mail
newdir
=
os
.
path
.
join
(
self
.
dirname
,
'new'
)
for
file
in
os
.
listdir
(
newdir
):
if
len
(
string
.
split
(
file
,
'.'
))
>
2
:
self
.
boxes
.
append
(
os
.
path
.
join
(
newdir
,
file
))
# Now check for current mail in this maildir
curdir
=
os
.
path
.
join
(
self
.
dirname
,
'cur'
)
for
file
in
os
.
listdir
(
curdir
):
if
len
(
string
.
split
(
file
,
'.'
))
>
2
:
self
.
boxes
.
append
(
os
.
path
.
join
(
curdir
,
file
))
def
next
(
self
):
if
not
self
.
boxes
:
return
None
fn
=
self
.
boxes
[
0
]
del
self
.
boxes
[
0
]
fp
=
open
(
os
.
path
.
join
(
self
.
dirname
,
fn
))
return
rfc822
.
Message
(
fp
)
# Qmail directory mailbox
def
__init__
(
self
,
dirname
):
import
string
self
.
dirname
=
dirname
self
.
boxes
=
[]
# check for new mail
newdir
=
os
.
path
.
join
(
self
.
dirname
,
'new'
)
for
file
in
os
.
listdir
(
newdir
):
if
len
(
string
.
split
(
file
,
'.'
))
>
2
:
self
.
boxes
.
append
(
os
.
path
.
join
(
newdir
,
file
))
# Now check for current mail in this maildir
curdir
=
os
.
path
.
join
(
self
.
dirname
,
'cur'
)
for
file
in
os
.
listdir
(
curdir
):
if
len
(
string
.
split
(
file
,
'.'
))
>
2
:
self
.
boxes
.
append
(
os
.
path
.
join
(
curdir
,
file
))
def
next
(
self
):
if
not
self
.
boxes
:
return
None
fn
=
self
.
boxes
[
0
]
del
self
.
boxes
[
0
]
fp
=
open
(
os
.
path
.
join
(
self
.
dirname
,
fn
))
return
rfc822
.
Message
(
fp
)
class
BabylMailbox
(
_Mailbox
):
def
_search_start
(
self
):
while
1
:
line
=
self
.
fp
.
readline
()
if
not
line
:
raise
EOFError
if
line
==
'*** EOOH ***
\
n
'
:
return
def
_search_end
(
self
):
while
1
:
pos
=
self
.
fp
.
tell
()
line
=
self
.
fp
.
readline
()
if
not
line
:
return
if
line
==
'
\
037
\
014
\
n
'
:
self
.
fp
.
seek
(
pos
)
return
def
_search_start
(
self
):
while
1
:
line
=
self
.
fp
.
readline
()
if
not
line
:
raise
EOFError
if
line
==
'*** EOOH ***
\
n
'
:
return
def
_search_end
(
self
):
while
1
:
pos
=
self
.
fp
.
tell
()
line
=
self
.
fp
.
readline
()
if
not
line
:
return
if
line
==
'
\
037
\
014
\
n
'
:
self
.
fp
.
seek
(
pos
)
return
def
_test
():
import
time
import
sys
import
string
import
os
args
=
sys
.
argv
[
1
:]
if
not
args
:
for
key
in
'MAILDIR'
,
'MAIL'
,
'LOGNAME'
,
'USER'
:
if
os
.
environ
.
has_key
(
key
):
mbox
=
os
.
environ
[
key
]
break
else
:
print
"$MAIL, $LOGNAME nor $USER set -- who are you?"
return
else
:
mbox
=
args
[
0
]
if
mbox
[:
1
]
==
'+'
:
mbox
=
os
.
environ
[
'HOME'
]
+
'/Mail/'
+
mbox
[
1
:]
elif
not
'/'
in
mbox
:
mbox
=
'/usr/mail/'
+
mbox
if
os
.
path
.
isdir
(
mbox
):
if
os
.
path
.
isdir
(
os
.
path
.
join
(
mbox
,
'cur'
)):
mb
=
Maildir
(
mbox
)
else
:
mb
=
MHMailbox
(
mbox
)
else
:
fp
=
open
(
mbox
,
'r'
)
mb
=
UnixMailbox
(
fp
)
msgs
=
[]
while
1
:
msg
=
mb
.
next
()
if
msg
is
None
:
break
msgs
.
append
(
msg
)
if
len
(
args
)
<=
1
:
msg
.
fp
=
None
if
len
(
args
)
>
1
:
num
=
string
.
atoi
(
args
[
1
])
print
'Message %d body:'
%
num
msg
=
msgs
[
num
-
1
]
msg
.
rewindbody
()
sys
.
stdout
.
write
(
msg
.
fp
.
read
())
else
:
print
'Mailbox'
,
mbox
,
'has'
,
len
(
msgs
),
'messages:'
for
msg
in
msgs
:
f
=
msg
.
getheader
(
'from'
)
or
""
s
=
msg
.
getheader
(
'subject'
)
or
""
d
=
msg
.
getheader
(
'date'
)
or
""
print
'%20.20s %18.18s %-30.30s'
%
(
f
,
d
[
5
:],
s
)
import
time
import
sys
import
string
import
os
args
=
sys
.
argv
[
1
:]
if
not
args
:
for
key
in
'MAILDIR'
,
'MAIL'
,
'LOGNAME'
,
'USER'
:
if
os
.
environ
.
has_key
(
key
):
mbox
=
os
.
environ
[
key
]
break
else
:
print
"$MAIL, $LOGNAME nor $USER set -- who are you?"
return
else
:
mbox
=
args
[
0
]
if
mbox
[:
1
]
==
'+'
:
mbox
=
os
.
environ
[
'HOME'
]
+
'/Mail/'
+
mbox
[
1
:]
elif
not
'/'
in
mbox
:
mbox
=
'/usr/mail/'
+
mbox
if
os
.
path
.
isdir
(
mbox
):
if
os
.
path
.
isdir
(
os
.
path
.
join
(
mbox
,
'cur'
)):
mb
=
Maildir
(
mbox
)
else
:
mb
=
MHMailbox
(
mbox
)
else
:
fp
=
open
(
mbox
,
'r'
)
mb
=
UnixMailbox
(
fp
)
msgs
=
[]
while
1
:
msg
=
mb
.
next
()
if
msg
is
None
:
break
msgs
.
append
(
msg
)
if
len
(
args
)
<=
1
:
msg
.
fp
=
None
if
len
(
args
)
>
1
:
num
=
string
.
atoi
(
args
[
1
])
print
'Message %d body:'
%
num
msg
=
msgs
[
num
-
1
]
msg
.
rewindbody
()
sys
.
stdout
.
write
(
msg
.
fp
.
read
())
else
:
print
'Mailbox'
,
mbox
,
'has'
,
len
(
msgs
),
'messages:'
for
msg
in
msgs
:
f
=
msg
.
getheader
(
'from'
)
or
""
s
=
msg
.
getheader
(
'subject'
)
or
""
d
=
msg
.
getheader
(
'date'
)
or
""
print
'%20.20s %18.18s %-30.30s'
%
(
f
,
d
[
5
:],
s
)
if
__name__
==
'__main__'
:
_test
()
_test
()
Lib/mimetypes.py
View file @
13a2c279
...
...
@@ -30,8 +30,8 @@ import urllib
knownfiles
=
[
"/usr/local/etc/httpd/conf/mime.types"
,
"/usr/local/lib/netscape/mime.types"
,
"/usr/local/etc/httpd/conf/mime.types"
,
# Apache 1.2
"/usr/local/etc/mime.types"
,
# Apache 1.3
"/usr/local/etc/httpd/conf/mime.types"
,
# Apache 1.2
"/usr/local/etc/mime.types"
,
# Apache 1.3
]
inited
=
0
...
...
@@ -56,24 +56,24 @@ def guess_type(url):
init
()
scheme
,
url
=
urllib
.
splittype
(
url
)
if
scheme
==
'data'
:
# syntax of data URLs:
# dataurl := "data:" [ mediatype ] [ ";base64" ] "," data
# mediatype := [ type "/" subtype ] *( ";" parameter )
# data := *urlchar
# parameter := attribute "=" value
# type/subtype defaults to "text/plain"
comma
=
string
.
find
(
url
,
','
)
if
comma
<
0
:
# bad data URL
return
None
,
None
semi
=
string
.
find
(
url
,
';'
,
0
,
comma
)
if
semi
>=
0
:
type
=
url
[:
semi
]
else
:
type
=
url
[:
comma
]
if
'='
in
type
or
'/'
not
in
type
:
type
=
'text/plain'
return
type
,
None
# never compressed, so encoding is None
# syntax of data URLs:
# dataurl := "data:" [ mediatype ] [ ";base64" ] "," data
# mediatype := [ type "/" subtype ] *( ";" parameter )
# data := *urlchar
# parameter := attribute "=" value
# type/subtype defaults to "text/plain"
comma
=
string
.
find
(
url
,
','
)
if
comma
<
0
:
# bad data URL
return
None
,
None
semi
=
string
.
find
(
url
,
';'
,
0
,
comma
)
if
semi
>=
0
:
type
=
url
[:
semi
]
else
:
type
=
url
[:
comma
]
if
'='
in
type
or
'/'
not
in
type
:
type
=
'text/plain'
return
type
,
None
# never compressed, so encoding is None
base
,
ext
=
posixpath
.
splitext
(
url
)
while
suffix_map
.
has_key
(
ext
):
base
,
ext
=
posixpath
.
splitext
(
base
+
suffix_map
[
ext
])
...
...
Lib/rfc822.py
View file @
13a2c279
...
...
@@ -332,11 +332,11 @@ class Message:
"""
raw
=
[]
for
h
in
self
.
getallmatchingheaders
(
name
):
if
h
[
0
]
in
'
\
t
'
:
raw
.
append
(
h
)
else
:
if
raw
:
raw
.
append
(
', '
)
if
h
[
0
]
in
'
\
t
'
:
raw
.
append
(
h
)
else
:
if
raw
:
raw
.
append
(
', '
)
i
=
string
.
find
(
h
,
':'
)
if
i
>
0
:
addr
=
h
[
i
+
1
:]
...
...
@@ -786,7 +786,7 @@ def dump_address_pair(pair):
_monthnames
=
[
'jan'
,
'feb'
,
'mar'
,
'apr'
,
'may'
,
'jun'
,
'jul'
,
'aug'
,
'sep'
,
'oct'
,
'nov'
,
'dec'
,
'january'
,
'february'
,
'march'
,
'april'
,
'may'
,
'june'
,
'july'
,
'january'
,
'february'
,
'march'
,
'april'
,
'may'
,
'june'
,
'july'
,
'august'
,
'september'
,
'october'
,
'november'
,
'december'
]
_daynames
=
[
'mon'
,
'tue'
,
'wed'
,
'thu'
,
'fri'
,
'sat'
,
'sun'
]
...
...
@@ -837,16 +837,16 @@ def parsedate_tz(data):
mm
=
_monthnames
.
index
(
mm
)
+
1
if
mm
>
12
:
mm
=
mm
-
12
if
dd
[
-
1
]
==
','
:
dd
=
dd
[:
-
1
]
dd
=
dd
[:
-
1
]
i
=
string
.
find
(
yy
,
':'
)
if
i
>
0
:
yy
,
tm
=
tm
,
yy
yy
,
tm
=
tm
,
yy
if
yy
[
-
1
]
==
','
:
yy
=
yy
[:
-
1
]
yy
=
yy
[:
-
1
]
if
yy
[
0
]
not
in
string
.
digits
:
yy
,
tz
=
tz
,
yy
yy
,
tz
=
tz
,
yy
if
tm
[
-
1
]
==
','
:
tm
=
tm
[:
-
1
]
tm
=
tm
[:
-
1
]
tm
=
string
.
splitfields
(
tm
,
':'
)
if
len
(
tm
)
==
2
:
[
thh
,
tmm
]
=
tm
...
...
Lib/shelve.py
View file @
13a2c279
...
...
@@ -10,19 +10,19 @@ are ordinary strings.
To summarize the interface (key is a string, data is an arbitrary
object):
import shelve
d = shelve.open(filename) # open, with (g)dbm filename -- no suffix
import shelve
d = shelve.open(filename) # open, with (g)dbm filename -- no suffix
d[key] = data
# store data at key (overwrites old data if
# using an existing key)
data = d[key]
# retrieve data at key (raise KeyError if no
# such key)
del d[key]
# delete data stored at key (raises KeyError
# if no such key)
flag = d.has_key(key)
# true if the key exists
list = d.keys()
# a list of all existing keys (slow!)
d[key] = data
# store data at key (overwrites old data if
# using an existing key)
data = d[key]
# retrieve data at key (raise KeyError if no
# such key)
del d[key]
# delete data stored at key (raises KeyError
# if no such key)
flag = d.has_key(key)
# true if the key exists
list = d.keys()
# a list of all existing keys (slow!)
d.close()
# close it
d.close()
# close it
Dependent on the implementation, closing a persistent dictionary may
or may not be necessary to flush changes to disk.
...
...
@@ -31,127 +31,127 @@ or may not be necessary to flush changes to disk.
# Try using cPickle and cStringIO if available.
try
:
from
cPickle
import
Pickler
,
Unpickler
from
cPickle
import
Pickler
,
Unpickler
except
ImportError
:
from
pickle
import
Pickler
,
Unpickler
from
pickle
import
Pickler
,
Unpickler
try
:
from
cStringIO
import
StringIO
from
cStringIO
import
StringIO
except
ImportError
:
from
StringIO
import
StringIO
from
StringIO
import
StringIO
class
Shelf
:
"""Base class for shelf implementations.
This is initialized with a dictionary-like object.
See the module's __doc__ string for an overview of the interface.
"""
def
__init__
(
self
,
dict
):
self
.
dict
=
dict
def
keys
(
self
):
return
self
.
dict
.
keys
()
def
__len__
(
self
):
return
len
(
self
.
dict
)
def
has_key
(
self
,
key
):
return
self
.
dict
.
has_key
(
key
)
def
get
(
self
,
key
,
default
=
None
):
if
self
.
dict
.
has_key
(
key
):
return
self
[
key
]
return
default
def
__getitem__
(
self
,
key
):
f
=
StringIO
(
self
.
dict
[
key
])
return
Unpickler
(
f
).
load
()
def
__setitem__
(
self
,
key
,
value
):
f
=
StringIO
()
p
=
Pickler
(
f
)
p
.
dump
(
value
)
self
.
dict
[
key
]
=
f
.
getvalue
()
def
__delitem__
(
self
,
key
):
del
self
.
dict
[
key
]
def
close
(
self
):
try
:
self
.
dict
.
close
()
except
:
pass
self
.
dict
=
0
def
__del__
(
self
):
self
.
close
()
def
sync
(
self
):
if
hasattr
(
self
.
dict
,
'sync'
):
self
.
dict
.
sync
()
"""Base class for shelf implementations.
This is initialized with a dictionary-like object.
See the module's __doc__ string for an overview of the interface.
"""
def
__init__
(
self
,
dict
):
self
.
dict
=
dict
def
keys
(
self
):
return
self
.
dict
.
keys
()
def
__len__
(
self
):
return
len
(
self
.
dict
)
def
has_key
(
self
,
key
):
return
self
.
dict
.
has_key
(
key
)
def
get
(
self
,
key
,
default
=
None
):
if
self
.
dict
.
has_key
(
key
):
return
self
[
key
]
return
default
def
__getitem__
(
self
,
key
):
f
=
StringIO
(
self
.
dict
[
key
])
return
Unpickler
(
f
).
load
()
def
__setitem__
(
self
,
key
,
value
):
f
=
StringIO
()
p
=
Pickler
(
f
)
p
.
dump
(
value
)
self
.
dict
[
key
]
=
f
.
getvalue
()
def
__delitem__
(
self
,
key
):
del
self
.
dict
[
key
]
def
close
(
self
):
try
:
self
.
dict
.
close
()
except
:
pass
self
.
dict
=
0
def
__del__
(
self
):
self
.
close
()
def
sync
(
self
):
if
hasattr
(
self
.
dict
,
'sync'
):
self
.
dict
.
sync
()
class
BsdDbShelf
(
Shelf
):
"""Shelf implementation using the "BSD" db interface.
"""Shelf implementation using the "BSD" db interface.
This adds methods first(), next(), previous(), last() and
set_location() that have no counterpart in [g]dbm databases.
This adds methods first(), next(), previous(), last() and
set_location() that have no counterpart in [g]dbm databases.
The actual database must be opened using one of the "bsddb"
modules "open" routines (i.e. bsddb.hashopen, bsddb.btopen or
bsddb.rnopen) and passed to the constructor.
The actual database must be opened using one of the "bsddb"
modules "open" routines (i.e. bsddb.hashopen, bsddb.btopen or
bsddb.rnopen) and passed to the constructor.
See the module's __doc__ string for an overview of the interface.
"""
See the module's __doc__ string for an overview of the interface.
"""
def
__init__
(
self
,
dict
):
Shelf
.
__init__
(
self
,
dict
)
def
__init__
(
self
,
dict
):
Shelf
.
__init__
(
self
,
dict
)
def
set_location
(
self
,
key
):
(
key
,
value
)
=
self
.
dict
.
set_location
(
key
)
f
=
StringIO
(
value
)
return
(
key
,
Unpickler
(
f
).
load
())
def
set_location
(
self
,
key
):
(
key
,
value
)
=
self
.
dict
.
set_location
(
key
)
f
=
StringIO
(
value
)
return
(
key
,
Unpickler
(
f
).
load
())
def
next
(
self
):
(
key
,
value
)
=
self
.
dict
.
next
()
f
=
StringIO
(
value
)
return
(
key
,
Unpickler
(
f
).
load
())
def
next
(
self
):
(
key
,
value
)
=
self
.
dict
.
next
()
f
=
StringIO
(
value
)
return
(
key
,
Unpickler
(
f
).
load
())
def
previous
(
self
):
(
key
,
value
)
=
self
.
dict
.
previous
()
f
=
StringIO
(
value
)
return
(
key
,
Unpickler
(
f
).
load
())
def
previous
(
self
):
(
key
,
value
)
=
self
.
dict
.
previous
()
f
=
StringIO
(
value
)
return
(
key
,
Unpickler
(
f
).
load
())
def
first
(
self
):
(
key
,
value
)
=
self
.
dict
.
first
()
f
=
StringIO
(
value
)
return
(
key
,
Unpickler
(
f
).
load
())
def
first
(
self
):
(
key
,
value
)
=
self
.
dict
.
first
()
f
=
StringIO
(
value
)
return
(
key
,
Unpickler
(
f
).
load
())
def
last
(
self
):
(
key
,
value
)
=
self
.
dict
.
last
()
f
=
StringIO
(
value
)
return
(
key
,
Unpickler
(
f
).
load
())
def
last
(
self
):
(
key
,
value
)
=
self
.
dict
.
last
()
f
=
StringIO
(
value
)
return
(
key
,
Unpickler
(
f
).
load
())
class
DbfilenameShelf
(
Shelf
):
"""Shelf implementation using the "anydbm" generic dbm interface.
"""Shelf implementation using the "anydbm" generic dbm interface.
This is initialized with the filename for the dbm database.
See the module's __doc__ string for an overview of the interface.
"""
def
__init__
(
self
,
filename
,
flag
=
'c'
):
import
anydbm
Shelf
.
__init__
(
self
,
anydbm
.
open
(
filename
,
flag
))
This is initialized with the filename for the dbm database.
See the module's __doc__ string for an overview of the interface.
"""
def
__init__
(
self
,
filename
,
flag
=
'c'
):
import
anydbm
Shelf
.
__init__
(
self
,
anydbm
.
open
(
filename
,
flag
))
def
open
(
filename
,
flag
=
'c'
):
"""Open a persistent dictionary for reading and writing.
"""Open a persistent dictionary for reading and writing.
Argument is the filename for the dbm database.
See the module's __doc__ string for an overview of the interface.
"""
return
DbfilenameShelf
(
filename
,
flag
)
Argument is the filename for the dbm database.
See the module's __doc__ string for an overview of the interface.
"""
return
DbfilenameShelf
(
filename
,
flag
)
Lib/stringold.py
View file @
13a2c279
...
...
@@ -199,10 +199,10 @@ def atof(s):
"""
if
type
(
s
)
==
_StringType
:
return
_float
(
s
)
return
_float
(
s
)
else
:
raise
TypeError
(
'argument 1: expected string, %s found'
%
type
(
s
).
__name__
)
raise
TypeError
(
'argument 1: expected string, %s found'
%
type
(
s
).
__name__
)
# Convert string to integer
def
atoi
(
*
args
):
...
...
@@ -217,18 +217,18 @@ def atoi(*args):
"""
try
:
s
=
args
[
0
]
s
=
args
[
0
]
except
IndexError
:
raise
TypeError
(
'function requires at least 1 argument: %d given'
%
len
(
args
))
raise
TypeError
(
'function requires at least 1 argument: %d given'
%
len
(
args
))
# Don't catch type error resulting from too many arguments to int(). The
# error message isn't compatible but the error type is, and this function
# is complicated enough already.
if
type
(
s
)
==
_StringType
:
return
_apply
(
_int
,
args
)
return
_apply
(
_int
,
args
)
else
:
raise
TypeError
(
'argument 1: expected string, %s found'
%
type
(
s
).
__name__
)
raise
TypeError
(
'argument 1: expected string, %s found'
%
type
(
s
).
__name__
)
# Convert string to long integer
...
...
@@ -245,18 +245,18 @@ def atol(*args):
"""
try
:
s
=
args
[
0
]
s
=
args
[
0
]
except
IndexError
:
raise
TypeError
(
'function requires at least 1 argument: %d given'
%
len
(
args
))
raise
TypeError
(
'function requires at least 1 argument: %d given'
%
len
(
args
))
# Don't catch type error resulting from too many arguments to long(). The
# error message isn't compatible but the error type is, and this function
# is complicated enough already.
if
type
(
s
)
==
_StringType
:
return
_apply
(
_long
,
args
)
return
_apply
(
_long
,
args
)
else
:
raise
TypeError
(
'argument 1: expected string, %s found'
%
type
(
s
).
__name__
)
raise
TypeError
(
'argument 1: expected string, %s found'
%
type
(
s
).
__name__
)
# Left-justify a string
...
...
@@ -298,8 +298,8 @@ def center(s, width):
if
n
<=
0
:
return
s
half
=
n
/
2
if
n
%
2
and
width
%
2
:
# This ensures that center(center(s, i), j) = center(s, j)
half
=
half
+
1
# This ensures that center(center(s, i), j) = center(s, j)
half
=
half
+
1
return
' '
*
half
+
s
+
' '
*
(
n
-
half
)
# Zero-fill a number, e.g., (12, 3) --> '012' and (-3, 3) --> '-03'
...
...
@@ -318,7 +318,7 @@ def zfill(x, width):
if
n
>=
width
:
return
s
sign
=
''
if
s
[
0
]
in
(
'-'
,
'+'
):
sign
,
s
=
s
[
0
],
s
[
1
:]
sign
,
s
=
s
[
0
],
s
[
1
:]
return
sign
+
'0'
*
(
width
-
n
)
+
s
# Expand tabs in a string.
...
...
@@ -333,12 +333,12 @@ def expandtabs(s, tabsize=8):
"""
res
=
line
=
''
for
c
in
s
:
if
c
==
'
\
t
'
:
c
=
' '
*
(
tabsize
-
len
(
line
)
%
tabsize
)
line
=
line
+
c
if
c
==
'
\
n
'
:
res
=
res
+
line
line
=
''
if
c
==
'
\
t
'
:
c
=
' '
*
(
tabsize
-
len
(
line
)
%
tabsize
)
line
=
line
+
c
if
c
==
'
\
n
'
:
res
=
res
+
line
line
=
''
return
res
+
line
# Character translation through look-up table.
...
...
@@ -387,14 +387,14 @@ def maketrans(fromstr, tostr):
"""
if
len
(
fromstr
)
!=
len
(
tostr
):
raise
ValueError
,
"maketrans arguments must have same length"
raise
ValueError
,
"maketrans arguments must have same length"
global
_idmapL
if
not
_idmapL
:
_idmapL
=
map
(
None
,
_idmap
)
_idmapL
=
map
(
None
,
_idmap
)
L
=
_idmapL
[:]
fromstr
=
map
(
ord
,
fromstr
)
for
i
in
range
(
len
(
fromstr
)):
L
[
fromstr
[
i
]]
=
tostr
[
i
]
L
[
fromstr
[
i
]]
=
tostr
[
i
]
return
joinfields
(
L
,
""
)
# Substring replacement (global)
...
...
@@ -428,4 +428,4 @@ try:
from
strop
import
maketrans
,
lowercase
,
uppercase
,
whitespace
letters
=
lowercase
+
uppercase
except
ImportError
:
pass
# Use the original versions
pass
# Use the original versions
Lib/urllib2.py
View file @
13a2c279
...
...
@@ -148,57 +148,57 @@ class URLError(IOError):
# URLError is a sub-type of IOError, but it doesn't share any of
# the implementation. need to override __init__ and __str__
def
__init__
(
self
,
reason
):
self
.
reason
=
reason
self
.
reason
=
reason
def
__str__
(
self
):
return
'<urlopen error %s>'
%
self
.
reason
return
'<urlopen error %s>'
%
self
.
reason
class
HTTPError
(
URLError
,
addinfourl
):
"""Raised when HTTP error occurs, but also acts like non-error return"""
def
__init__
(
self
,
url
,
code
,
msg
,
hdrs
,
fp
):
addinfourl
.
__init__
(
self
,
fp
,
hdrs
,
url
)
self
.
code
=
code
self
.
msg
=
msg
self
.
hdrs
=
hdrs
self
.
fp
=
fp
# XXX
self
.
filename
=
url
addinfourl
.
__init__
(
self
,
fp
,
hdrs
,
url
)
self
.
code
=
code
self
.
msg
=
msg
self
.
hdrs
=
hdrs
self
.
fp
=
fp
# XXX
self
.
filename
=
url
def
__str__
(
self
):
return
'HTTP Error %s: %s'
%
(
self
.
code
,
self
.
msg
)
return
'HTTP Error %s: %s'
%
(
self
.
code
,
self
.
msg
)
def
__del__
(
self
):
# XXX is this safe? what if user catches exception, then
# extracts fp and discards exception?
self
.
fp
.
close
()
# XXX is this safe? what if user catches exception, then
# extracts fp and discards exception?
self
.
fp
.
close
()
class
GopherError
(
URLError
):
pass
class
Request
:
def
__init__
(
self
,
url
,
data
=
None
,
headers
=
{}):
# unwrap('<URL:type://host/path>') --> 'type://host/path'
self
.
__original
=
unwrap
(
url
)
self
.
type
=
None
# self.__r_type is what's left after doing the splittype
self
.
host
=
None
self
.
port
=
None
# unwrap('<URL:type://host/path>') --> 'type://host/path'
self
.
__original
=
unwrap
(
url
)
self
.
type
=
None
# self.__r_type is what's left after doing the splittype
self
.
host
=
None
self
.
port
=
None
self
.
data
=
data
self
.
headers
=
{}
self
.
headers
=
{}
self
.
headers
.
update
(
headers
)
def
__getattr__
(
self
,
attr
):
# XXX this is a fallback mechanism to guard against these
# methods getting called in a non-standard order. this may be
# too complicated and/or unnecessary.
# XXX should the __r_XXX attributes be public?
if
attr
[:
12
]
==
'_Request__r_'
:
name
=
attr
[
12
:]
if
hasattr
(
Request
,
'get_'
+
name
):
getattr
(
self
,
'get_'
+
name
)()
return
getattr
(
self
,
attr
)
raise
AttributeError
,
attr
# XXX this is a fallback mechanism to guard against these
# methods getting called in a non-standard order. this may be
# too complicated and/or unnecessary.
# XXX should the __r_XXX attributes be public?
if
attr
[:
12
]
==
'_Request__r_'
:
name
=
attr
[
12
:]
if
hasattr
(
Request
,
'get_'
+
name
):
getattr
(
self
,
'get_'
+
name
)()
return
getattr
(
self
,
attr
)
raise
AttributeError
,
attr
def
add_data
(
self
,
data
):
self
.
data
=
data
...
...
@@ -213,34 +213,34 @@ class Request:
return
self
.
__original
def
get_type
(
self
):
if
self
.
type
is
None
:
self
.
type
,
self
.
__r_type
=
splittype
(
self
.
__original
)
return
self
.
type
if
self
.
type
is
None
:
self
.
type
,
self
.
__r_type
=
splittype
(
self
.
__original
)
return
self
.
type
def
get_host
(
self
):
if
self
.
host
is
None
:
self
.
host
,
self
.
__r_host
=
splithost
(
self
.
__r_type
)
if
self
.
host
:
self
.
host
=
unquote
(
self
.
host
)
return
self
.
host
if
self
.
host
is
None
:
self
.
host
,
self
.
__r_host
=
splithost
(
self
.
__r_type
)
if
self
.
host
:
self
.
host
=
unquote
(
self
.
host
)
return
self
.
host
def
get_selector
(
self
):
return
self
.
__r_host
return
self
.
__r_host
def
set_proxy
(
self
,
proxy
):
self
.
__proxy
=
proxy
# XXX this code is based on urllib, but it doesn't seem
# correct. specifically, if the proxy has a port number then
# splittype will return the hostname as the type and the port
# will be include with everything else
self
.
type
,
self
.
__r_type
=
splittype
(
self
.
__proxy
)
self
.
host
,
XXX
=
splithost
(
self
.
__r_type
)
self
.
host
=
unquote
(
self
.
host
)
self
.
__r_host
=
self
.
__original
self
.
__proxy
=
proxy
# XXX this code is based on urllib, but it doesn't seem
# correct. specifically, if the proxy has a port number then
# splittype will return the hostname as the type and the port
# will be include with everything else
self
.
type
,
self
.
__r_type
=
splittype
(
self
.
__proxy
)
self
.
host
,
XXX
=
splithost
(
self
.
__r_type
)
self
.
host
=
unquote
(
self
.
host
)
self
.
__r_host
=
self
.
__original
def
add_header
(
self
,
key
,
val
):
# useful for something like authentication
self
.
headers
[
key
]
=
val
# useful for something like authentication
self
.
headers
[
key
]
=
val
class
OpenerDirector
:
def
__init__
(
self
):
...
...
@@ -302,21 +302,21 @@ class OpenerDirector:
return
result
def
open
(
self
,
fullurl
,
data
=
None
):
# accept a URL or a Request object
if
type
(
fullurl
)
==
types
.
StringType
:
req
=
Request
(
fullurl
,
data
)
# accept a URL or a Request object
if
type
(
fullurl
)
==
types
.
StringType
:
req
=
Request
(
fullurl
,
data
)
else
:
req
=
fullurl
if
data
is
not
None
:
req
.
add_data
(
data
)
assert
isinstance
(
req
,
Request
)
# really only care about interface
assert
isinstance
(
req
,
Request
)
# really only care about interface
result
=
self
.
_call_chain
(
self
.
handle_open
,
'default'
,
'default_open'
,
req
)
if
result
:
return
result
type_
=
req
.
get_type
()
type_
=
req
.
get_type
()
result
=
self
.
_call_chain
(
self
.
handle_open
,
type_
,
type_
+
\
'_open'
,
req
)
if
result
:
...
...
@@ -350,11 +350,11 @@ def is_callable(obj):
# not quite like builtin callable (which I didn't know existed),
# not entirely sure it needs to be different
if
type
(
obj
)
in
(
types
.
BuiltinFunctionType
,
types
.
BuiltinMethodType
,
types
.
LambdaType
,
types
.
MethodType
):
return
1
types
.
BuiltinMethodType
,
types
.
LambdaType
,
types
.
MethodType
):
return
1
if
type
(
obj
)
==
types
.
InstanceType
:
return
hasattr
(
obj
,
'__call__'
)
return
hasattr
(
obj
,
'__call__'
)
return
0
def
get_methods
(
inst
):
...
...
@@ -370,8 +370,8 @@ def get_methods(inst):
if
type
(
attr
)
==
types
.
UnboundMethodType
:
methods
[
name
]
=
1
for
name
in
dir
(
inst
):
if
is_callable
(
getattr
(
inst
,
name
)):
methods
[
name
]
=
1
if
is_callable
(
getattr
(
inst
,
name
)):
methods
[
name
]
=
1
return
methods
.
keys
()
# XXX probably also want an abstract factory that knows things like
...
...
@@ -423,7 +423,7 @@ class BaseHandler:
class
HTTPDefaultErrorHandler
(
BaseHandler
):
def
http_error_default
(
self
,
req
,
fp
,
code
,
msg
,
hdrs
):
raise
HTTPError
(
req
.
get_full_url
(),
code
,
msg
,
hdrs
,
fp
)
raise
HTTPError
(
req
.
get_full_url
(),
code
,
msg
,
hdrs
,
fp
)
class
HTTPRedirectHandler
(
BaseHandler
):
# Implementation note: To avoid the server sending us into an
...
...
@@ -461,114 +461,114 @@ class HTTPRedirectHandler(BaseHandler):
class
ProxyHandler
(
BaseHandler
):
def
__init__
(
self
,
proxies
=
None
):
if
proxies
is
None
:
proxies
=
getproxies
()
assert
hasattr
(
proxies
,
'has_key'
),
"proxies must be a mapping"
self
.
proxies
=
proxies
for
type
,
url
in
proxies
.
items
():
setattr
(
self
,
'%s_open'
%
type
,
lambda
r
,
proxy
=
url
,
type
=
type
,
meth
=
self
.
proxy_open
:
\
meth
(
r
,
proxy
,
type
))
if
proxies
is
None
:
proxies
=
getproxies
()
assert
hasattr
(
proxies
,
'has_key'
),
"proxies must be a mapping"
self
.
proxies
=
proxies
for
type
,
url
in
proxies
.
items
():
setattr
(
self
,
'%s_open'
%
type
,
lambda
r
,
proxy
=
url
,
type
=
type
,
meth
=
self
.
proxy_open
:
\
meth
(
r
,
proxy
,
type
))
def
proxy_open
(
self
,
req
,
proxy
,
type
):
orig_type
=
req
.
get_type
()
req
.
set_proxy
(
proxy
)
if
orig_type
==
type
:
# let other handlers take care of it
# XXX this only makes sense if the proxy is before the
# other handlers
return
None
else
:
# need to start over, because the other handlers don't
# grok the proxy's URL type
return
self
.
parent
.
open
(
req
)
orig_type
=
req
.
get_type
()
req
.
set_proxy
(
proxy
)
if
orig_type
==
type
:
# let other handlers take care of it
# XXX this only makes sense if the proxy is before the
# other handlers
return
None
else
:
# need to start over, because the other handlers don't
# grok the proxy's URL type
return
self
.
parent
.
open
(
req
)
# feature suggested by Duncan Booth
# XXX custom is not a good name
class
CustomProxy
:
# either pass a function to the constructor or override handle
def
__init__
(
self
,
proto
,
func
=
None
,
proxy_addr
=
None
):
self
.
proto
=
proto
self
.
func
=
func
self
.
addr
=
proxy_addr
self
.
proto
=
proto
self
.
func
=
func
self
.
addr
=
proxy_addr
def
handle
(
self
,
req
):
if
self
.
func
and
self
.
func
(
req
):
return
1
if
self
.
func
and
self
.
func
(
req
):
return
1
def
get_proxy
(
self
):
return
self
.
addr
return
self
.
addr
class
CustomProxyHandler
(
BaseHandler
):
def
__init__
(
self
,
*
proxies
):
self
.
proxies
=
{}
self
.
proxies
=
{}
def
proxy_open
(
self
,
req
):
proto
=
req
.
get_type
()
try
:
proxies
=
self
.
proxies
[
proto
]
except
KeyError
:
return
None
for
p
in
proxies
:
if
p
.
handle
(
req
):
req
.
set_proxy
(
p
.
get_proxy
())
return
self
.
parent
.
open
(
req
)
return
None
proto
=
req
.
get_type
()
try
:
proxies
=
self
.
proxies
[
proto
]
except
KeyError
:
return
None
for
p
in
proxies
:
if
p
.
handle
(
req
):
req
.
set_proxy
(
p
.
get_proxy
())
return
self
.
parent
.
open
(
req
)
return
None
def
do_proxy
(
self
,
p
,
req
):
p
return
self
.
parent
.
open
(
req
)
p
return
self
.
parent
.
open
(
req
)
def
add_proxy
(
self
,
cpo
):
if
self
.
proxies
.
has_key
(
cpo
.
proto
):
self
.
proxies
[
cpo
.
proto
].
append
(
cpo
)
else
:
self
.
proxies
[
cpo
.
proto
]
=
[
cpo
]
if
self
.
proxies
.
has_key
(
cpo
.
proto
):
self
.
proxies
[
cpo
.
proto
].
append
(
cpo
)
else
:
self
.
proxies
[
cpo
.
proto
]
=
[
cpo
]
class
HTTPPasswordMgr
:
def
__init__
(
self
):
self
.
passwd
=
{}
self
.
passwd
=
{}
def
add_password
(
self
,
realm
,
uri
,
user
,
passwd
):
# uri could be a single URI or a sequence
if
type
(
uri
)
==
types
.
StringType
:
uri
=
[
uri
]
uri
=
tuple
(
map
(
self
.
reduce_uri
,
uri
))
if
not
self
.
passwd
.
has_key
(
realm
):
self
.
passwd
[
realm
]
=
{}
self
.
passwd
[
realm
][
uri
]
=
(
user
,
passwd
)
# uri could be a single URI or a sequence
if
type
(
uri
)
==
types
.
StringType
:
uri
=
[
uri
]
uri
=
tuple
(
map
(
self
.
reduce_uri
,
uri
))
if
not
self
.
passwd
.
has_key
(
realm
):
self
.
passwd
[
realm
]
=
{}
self
.
passwd
[
realm
][
uri
]
=
(
user
,
passwd
)
def
find_user_password
(
self
,
realm
,
authuri
):
domains
=
self
.
passwd
.
get
(
realm
,
{})
authuri
=
self
.
reduce_uri
(
authuri
)
for
uris
,
authinfo
in
domains
.
items
():
for
uri
in
uris
:
if
self
.
is_suburi
(
uri
,
authuri
):
return
authinfo
return
None
,
None
domains
=
self
.
passwd
.
get
(
realm
,
{})
authuri
=
self
.
reduce_uri
(
authuri
)
for
uris
,
authinfo
in
domains
.
items
():
for
uri
in
uris
:
if
self
.
is_suburi
(
uri
,
authuri
):
return
authinfo
return
None
,
None
def
reduce_uri
(
self
,
uri
):
"""Accept netloc or URI and extract only the netloc and path"""
parts
=
urlparse
.
urlparse
(
uri
)
if
parts
[
1
]:
return
parts
[
1
],
parts
[
2
]
or
'/'
else
:
return
parts
[
2
],
'/'
"""Accept netloc or URI and extract only the netloc and path"""
parts
=
urlparse
.
urlparse
(
uri
)
if
parts
[
1
]:
return
parts
[
1
],
parts
[
2
]
or
'/'
else
:
return
parts
[
2
],
'/'
def
is_suburi
(
self
,
base
,
test
):
"""Check if test is below base in a URI tree
Both args must be URIs in reduced form.
"""
if
base
==
test
:
return
1
if
base
[
0
]
!=
test
[
0
]:
return
0
common
=
os
.
path
.
commonprefix
((
base
[
1
],
test
[
1
]))
if
len
(
common
)
==
len
(
base
[
1
]):
return
1
return
0
"""Check if test is below base in a URI tree
Both args must be URIs in reduced form.
"""
if
base
==
test
:
return
1
if
base
[
0
]
!=
test
[
0
]:
return
0
common
=
os
.
path
.
commonprefix
((
base
[
1
],
test
[
1
]))
if
len
(
common
)
==
len
(
base
[
1
]):
return
1
return
0
class
HTTPBasicAuthHandler
(
BaseHandler
):
rx
=
re
.
compile
(
'[
\
t
]*([^
\
t
]+)[
\
t
]+realm="([^"]*)"'
)
...
...
@@ -579,15 +579,15 @@ class HTTPBasicAuthHandler(BaseHandler):
def
__init__
(
self
):
self
.
passwd
=
HTTPPasswordMgr
()
self
.
add_password
=
self
.
passwd
.
add_password
self
.
__current_realm
=
None
# if __current_realm is not None, then the server must have
# refused our name/password and is asking for authorization
# again. must be careful to set it to None on successful
# return.
self
.
add_password
=
self
.
passwd
.
add_password
self
.
__current_realm
=
None
# if __current_realm is not None, then the server must have
# refused our name/password and is asking for authorization
# again. must be careful to set it to None on successful
# return.
def
http_error_401
(
self
,
req
,
fp
,
code
,
msg
,
headers
):
# XXX could be mult. headers
# XXX could be mult. headers
authreq
=
headers
.
get
(
'www-authenticate'
,
None
)
if
authreq
:
mo
=
HTTPBasicAuthHandler
.
rx
.
match
(
authreq
)
...
...
@@ -597,23 +597,23 @@ class HTTPBasicAuthHandler(BaseHandler):
return
self
.
retry_http_basic_auth
(
req
,
realm
)
def
retry_http_basic_auth
(
self
,
req
,
realm
):
if
self
.
__current_realm
is
None
:
self
.
__current_realm
=
realm
else
:
self
.
__current_realm
=
realm
return
None
# XXX host isn't really the correct URI?
if
self
.
__current_realm
is
None
:
self
.
__current_realm
=
realm
else
:
self
.
__current_realm
=
realm
return
None
# XXX host isn't really the correct URI?
host
=
req
.
get_host
()
user
,
pw
=
self
.
passwd
.
find_user_password
(
realm
,
host
)
if
pw
:
raw
=
"%s:%s"
%
(
user
,
pw
)
auth
=
string
.
strip
(
base64
.
encodestring
(
raw
))
raw
=
"%s:%s"
%
(
user
,
pw
)
auth
=
string
.
strip
(
base64
.
encodestring
(
raw
))
req
.
add_header
(
'Authorization'
,
'Basic %s'
%
auth
)
resp
=
self
.
parent
.
open
(
req
)
self
.
__current_realm
=
None
return
resp
self
.
__current_realm
=
None
return
resp
else
:
self
.
__current_realm
=
None
self
.
__current_realm
=
None
return
None
class
HTTPDigestAuthHandler
(
BaseHandler
):
...
...
@@ -624,111 +624,111 @@ class HTTPDigestAuthHandler(BaseHandler):
"""
def
__init__
(
self
):
self
.
passwd
=
HTTPPasswordMgr
()
self
.
add_password
=
self
.
passwd
.
add_password
self
.
__current_realm
=
None
self
.
passwd
=
HTTPPasswordMgr
()
self
.
add_password
=
self
.
passwd
.
add_password
self
.
__current_realm
=
None
def
http_error_401
(
self
,
req
,
fp
,
code
,
msg
,
headers
):
# XXX could be mult. headers
authreq
=
headers
.
get
(
'www-authenticate'
,
None
)
if
authreq
:
kind
=
string
.
split
(
authreq
)[
0
]
if
kind
==
'Digest'
:
return
self
.
retry_http_digest_auth
(
req
,
authreq
)
# XXX could be mult. headers
authreq
=
headers
.
get
(
'www-authenticate'
,
None
)
if
authreq
:
kind
=
string
.
split
(
authreq
)[
0
]
if
kind
==
'Digest'
:
return
self
.
retry_http_digest_auth
(
req
,
authreq
)
def
retry_http_digest_auth
(
self
,
req
,
auth
):
token
,
challenge
=
string
.
split
(
auth
,
' '
,
1
)
chal
=
parse_keqv_list
(
parse_http_list
(
challenge
))
auth
=
self
.
get_authorization
(
req
,
chal
)
if
auth
:
req
.
add_header
(
'Authorization'
,
'Digest %s'
%
auth
)
resp
=
self
.
parent
.
open
(
req
)
self
.
__current_realm
=
None
return
resp
token
,
challenge
=
string
.
split
(
auth
,
' '
,
1
)
chal
=
parse_keqv_list
(
parse_http_list
(
challenge
))
auth
=
self
.
get_authorization
(
req
,
chal
)
if
auth
:
req
.
add_header
(
'Authorization'
,
'Digest %s'
%
auth
)
resp
=
self
.
parent
.
open
(
req
)
self
.
__current_realm
=
None
return
resp
def
get_authorization
(
self
,
req
,
chal
):
try
:
realm
=
chal
[
'realm'
]
nonce
=
chal
[
'nonce'
]
algorithm
=
chal
.
get
(
'algorithm'
,
'MD5'
)
# mod_digest doesn't send an opaque, even though it isn't
# supposed to be optional
opaque
=
chal
.
get
(
'opaque'
,
None
)
except
KeyError
:
return
None
if
self
.
__current_realm
is
None
:
self
.
__current_realm
=
realm
else
:
self
.
__current_realm
=
realm
return
None
H
,
KD
=
self
.
get_algorithm_impls
(
algorithm
)
if
H
is
None
:
return
None
user
,
pw
=
self
.
passwd
.
find_user_password
(
realm
,
req
.
get_full_url
())
if
user
is
None
:
return
None
# XXX not implemented yet
if
req
.
has_data
():
entdig
=
self
.
get_entity_digest
(
req
.
get_data
(),
chal
)
else
:
entdig
=
None
A1
=
"%s:%s:%s"
%
(
user
,
realm
,
pw
)
A2
=
"%s:%s"
%
(
req
.
has_data
()
and
'POST'
or
'GET'
,
# XXX selector: what about proxies and full urls
req
.
get_selector
())
respdig
=
KD
(
H
(
A1
),
"%s:%s"
%
(
nonce
,
H
(
A2
)))
# XXX should the partial digests be encoded too?
base
=
'username="%s", realm="%s", nonce="%s", uri="%s", '
\
'response="%s"'
%
(
user
,
realm
,
nonce
,
req
.
get_selector
(),
respdig
)
if
opaque
:
base
=
base
+
', opaque="%s"'
%
opaque
if
entdig
:
base
=
base
+
', digest="%s"'
%
entdig
if
algorithm
!=
'MD5'
:
base
=
base
+
', algorithm="%s"'
%
algorithm
return
base
try
:
realm
=
chal
[
'realm'
]
nonce
=
chal
[
'nonce'
]
algorithm
=
chal
.
get
(
'algorithm'
,
'MD5'
)
# mod_digest doesn't send an opaque, even though it isn't
# supposed to be optional
opaque
=
chal
.
get
(
'opaque'
,
None
)
except
KeyError
:
return
None
if
self
.
__current_realm
is
None
:
self
.
__current_realm
=
realm
else
:
self
.
__current_realm
=
realm
return
None
H
,
KD
=
self
.
get_algorithm_impls
(
algorithm
)
if
H
is
None
:
return
None
user
,
pw
=
self
.
passwd
.
find_user_password
(
realm
,
req
.
get_full_url
())
if
user
is
None
:
return
None
# XXX not implemented yet
if
req
.
has_data
():
entdig
=
self
.
get_entity_digest
(
req
.
get_data
(),
chal
)
else
:
entdig
=
None
A1
=
"%s:%s:%s"
%
(
user
,
realm
,
pw
)
A2
=
"%s:%s"
%
(
req
.
has_data
()
and
'POST'
or
'GET'
,
# XXX selector: what about proxies and full urls
req
.
get_selector
())
respdig
=
KD
(
H
(
A1
),
"%s:%s"
%
(
nonce
,
H
(
A2
)))
# XXX should the partial digests be encoded too?
base
=
'username="%s", realm="%s", nonce="%s", uri="%s", '
\
'response="%s"'
%
(
user
,
realm
,
nonce
,
req
.
get_selector
(),
respdig
)
if
opaque
:
base
=
base
+
', opaque="%s"'
%
opaque
if
entdig
:
base
=
base
+
', digest="%s"'
%
entdig
if
algorithm
!=
'MD5'
:
base
=
base
+
', algorithm="%s"'
%
algorithm
return
base
def
get_algorithm_impls
(
self
,
algorithm
):
# lambdas assume digest modules are imported at the top level
if
algorithm
==
'MD5'
:
H
=
lambda
x
,
e
=
encode_digest
:
e
(
md5
.
new
(
x
).
digest
())
elif
algorithm
==
'SHA'
:
H
=
lambda
x
,
e
=
encode_digest
:
e
(
sha
.
new
(
x
).
digest
())
# XXX MD5-sess
KD
=
lambda
s
,
d
,
H
=
H
:
H
(
"%s:%s"
%
(
s
,
d
))
return
H
,
KD
# lambdas assume digest modules are imported at the top level
if
algorithm
==
'MD5'
:
H
=
lambda
x
,
e
=
encode_digest
:
e
(
md5
.
new
(
x
).
digest
())
elif
algorithm
==
'SHA'
:
H
=
lambda
x
,
e
=
encode_digest
:
e
(
sha
.
new
(
x
).
digest
())
# XXX MD5-sess
KD
=
lambda
s
,
d
,
H
=
H
:
H
(
"%s:%s"
%
(
s
,
d
))
return
H
,
KD
def
get_entity_digest
(
self
,
data
,
chal
):
# XXX not implemented yet
return
None
# XXX not implemented yet
return
None
def
encode_digest
(
digest
):
hexrep
=
[]
for
c
in
digest
:
n
=
(
ord
(
c
)
>>
4
)
&
0xf
hexrep
.
append
(
hex
(
n
)[
-
1
])
n
=
ord
(
c
)
&
0xf
hexrep
.
append
(
hex
(
n
)[
-
1
])
n
=
(
ord
(
c
)
>>
4
)
&
0xf
hexrep
.
append
(
hex
(
n
)[
-
1
])
n
=
ord
(
c
)
&
0xf
hexrep
.
append
(
hex
(
n
)[
-
1
])
return
string
.
join
(
hexrep
,
''
)
class
HTTPHandler
(
BaseHandler
):
def
http_open
(
self
,
req
):
# XXX devise a new mechanism to specify user/password
host
=
req
.
get_host
()
host
=
req
.
get_host
()
if
not
host
:
raise
URLError
(
'no host given'
)
h
=
httplib
.
HTTP
(
host
)
# will parse host:port
##
h.set_debuglevel(1)
##
h.set_debuglevel(1)
if
req
.
has_data
():
data
=
req
.
get_data
()
h
.
putrequest
(
'POST'
,
req
.
get_selector
())
...
...
@@ -740,8 +740,8 @@ class HTTPHandler(BaseHandler):
h
.
putheader
(
'Host'
,
host
)
for
args
in
self
.
parent
.
addheaders
:
apply
(
h
.
putheader
,
args
)
for
k
,
v
in
req
.
headers
.
items
():
h
.
putheader
(
k
,
v
)
for
k
,
v
in
req
.
headers
.
items
():
h
.
putheader
(
k
,
v
)
h
.
endheaders
()
if
req
.
has_data
():
h
.
send
(
data
+
'
\
r
\
n
'
)
...
...
@@ -761,17 +761,17 @@ class HTTPHandler(BaseHandler):
class
UnknownHandler
(
BaseHandler
):
def
unknown_open
(
self
,
req
):
type
=
req
.
get_type
()
type
=
req
.
get_type
()
raise
URLError
(
'unknown url type: %s'
%
type
)
def
parse_keqv_list
(
l
):
"""Parse list of key=value strings where keys are not duplicated."""
parsed
=
{}
for
elt
in
l
:
k
,
v
=
string
.
split
(
elt
,
'='
,
1
)
if
v
[
0
]
==
'"'
and
v
[
-
1
]
==
'"'
:
v
=
v
[
1
:
-
1
]
parsed
[
k
]
=
v
k
,
v
=
string
.
split
(
elt
,
'='
,
1
)
if
v
[
0
]
==
'"'
and
v
[
-
1
]
==
'"'
:
v
=
v
[
1
:
-
1
]
parsed
[
k
]
=
v
return
parsed
def
parse_http_list
(
s
):
...
...
@@ -789,104 +789,104 @@ def parse_http_list(s):
inquote
=
0
start
=
0
while
i
<
end
:
cur
=
s
[
i
:]
c
=
string
.
find
(
cur
,
','
)
q
=
string
.
find
(
cur
,
'"'
)
if
c
==
-
1
:
list
.
append
(
s
[
start
:])
break
if
q
==
-
1
:
if
inquote
:
raise
ValueError
,
"unbalanced quotes"
else
:
list
.
append
(
s
[
start
:
i
+
c
])
i
=
i
+
c
+
1
continue
if
inquote
:
if
q
<
c
:
list
.
append
(
s
[
start
:
i
+
c
])
i
=
i
+
c
+
1
start
=
i
inquote
=
0
else
:
i
=
i
+
q
else
:
if
c
<
q
:
list
.
append
(
s
[
start
:
i
+
c
])
i
=
i
+
c
+
1
start
=
i
else
:
inquote
=
1
i
=
i
+
q
+
1
cur
=
s
[
i
:]
c
=
string
.
find
(
cur
,
','
)
q
=
string
.
find
(
cur
,
'"'
)
if
c
==
-
1
:
list
.
append
(
s
[
start
:])
break
if
q
==
-
1
:
if
inquote
:
raise
ValueError
,
"unbalanced quotes"
else
:
list
.
append
(
s
[
start
:
i
+
c
])
i
=
i
+
c
+
1
continue
if
inquote
:
if
q
<
c
:
list
.
append
(
s
[
start
:
i
+
c
])
i
=
i
+
c
+
1
start
=
i
inquote
=
0
else
:
i
=
i
+
q
else
:
if
c
<
q
:
list
.
append
(
s
[
start
:
i
+
c
])
i
=
i
+
c
+
1
start
=
i
else
:
inquote
=
1
i
=
i
+
q
+
1
return
map
(
string
.
strip
,
list
)
class
FileHandler
(
BaseHandler
):
# Use local file or FTP depending on form of URL
def
file_open
(
self
,
req
):
url
=
req
.
get_selector
()
if
url
[:
2
]
==
'//'
and
url
[
2
:
3
]
!=
'/'
:
req
.
type
=
'ftp'
return
self
.
parent
.
open
(
req
)
else
:
return
self
.
open_local_file
(
req
)
url
=
req
.
get_selector
()
if
url
[:
2
]
==
'//'
and
url
[
2
:
3
]
!=
'/'
:
req
.
type
=
'ftp'
return
self
.
parent
.
open
(
req
)
else
:
return
self
.
open_local_file
(
req
)
# names for the localhost
names
=
None
def
get_names
(
self
):
if
FileHandler
.
names
is
None
:
FileHandler
.
names
=
(
socket
.
gethostbyname
(
'localhost'
),
socket
.
gethostbyname
(
socket
.
gethostname
()))
return
FileHandler
.
names
if
FileHandler
.
names
is
None
:
FileHandler
.
names
=
(
socket
.
gethostbyname
(
'localhost'
),
socket
.
gethostbyname
(
socket
.
gethostname
()))
return
FileHandler
.
names
# not entirely sure what the rules are here
def
open_local_file
(
self
,
req
):
mtype
=
mimetypes
.
guess_type
(
req
.
get_selector
())[
0
]
headers
=
mimetools
.
Message
(
StringIO
(
'Content-Type: %s
\
n
'
\
%
(
mtype
or
'text/plain'
)))
host
=
req
.
get_host
()
file
=
req
.
get_selector
()
if
host
:
host
,
port
=
splitport
(
host
)
if
not
host
or
\
(
not
port
and
socket
.
gethostbyname
(
host
)
in
self
.
get_names
()):
return
addinfourl
(
open
(
url2pathname
(
file
),
'rb'
),
headers
,
'file:'
+
file
)
raise
URLError
(
'file not on local host'
)
mtype
=
mimetypes
.
guess_type
(
req
.
get_selector
())[
0
]
headers
=
mimetools
.
Message
(
StringIO
(
'Content-Type: %s
\
n
'
\
%
(
mtype
or
'text/plain'
)))
host
=
req
.
get_host
()
file
=
req
.
get_selector
()
if
host
:
host
,
port
=
splitport
(
host
)
if
not
host
or
\
(
not
port
and
socket
.
gethostbyname
(
host
)
in
self
.
get_names
()):
return
addinfourl
(
open
(
url2pathname
(
file
),
'rb'
),
headers
,
'file:'
+
file
)
raise
URLError
(
'file not on local host'
)
class
FTPHandler
(
BaseHandler
):
def
ftp_open
(
self
,
req
):
host
=
req
.
get_host
()
if
not
host
:
raise
IOError
,
(
'ftp error'
,
'no host given'
)
# XXX handle custom username & password
host
=
socket
.
gethostbyname
(
host
)
host
,
port
=
splitport
(
host
)
if
port
is
None
:
port
=
ftplib
.
FTP_PORT
path
,
attrs
=
splitattr
(
req
.
get_selector
())
path
=
unquote
(
path
)
dirs
=
string
.
splitfields
(
path
,
'/'
)
dirs
,
file
=
dirs
[:
-
1
],
dirs
[
-
1
]
if
dirs
and
not
dirs
[
0
]:
dirs
=
dirs
[
1
:]
user
=
passwd
=
''
# XXX
try
:
fw
=
self
.
connect_ftp
(
user
,
passwd
,
host
,
port
,
dirs
)
type
=
file
and
'I'
or
'D'
for
attr
in
attrs
:
attr
,
value
=
splitattr
(
attr
)
if
string
.
lower
(
attr
)
==
'type'
and
\
value
in
(
'a'
,
'A'
,
'i'
,
'I'
,
'd'
,
'D'
):
type
=
string
.
upper
(
value
)
fp
,
retrlen
=
fw
.
retrfile
(
file
,
type
)
if
retrlen
is
not
None
and
retrlen
>=
0
:
sf
=
StringIO
(
'Content-Length: %d
\
n
'
%
retrlen
)
headers
=
mimetools
.
Message
(
sf
)
else
:
headers
=
noheaders
()
return
addinfourl
(
fp
,
headers
,
req
.
get_full_url
())
except
ftplib
.
all_errors
,
msg
:
raise
IOError
,
(
'ftp error'
,
msg
),
sys
.
exc_info
()[
2
]
host
=
req
.
get_host
()
if
not
host
:
raise
IOError
,
(
'ftp error'
,
'no host given'
)
# XXX handle custom username & password
host
=
socket
.
gethostbyname
(
host
)
host
,
port
=
splitport
(
host
)
if
port
is
None
:
port
=
ftplib
.
FTP_PORT
path
,
attrs
=
splitattr
(
req
.
get_selector
())
path
=
unquote
(
path
)
dirs
=
string
.
splitfields
(
path
,
'/'
)
dirs
,
file
=
dirs
[:
-
1
],
dirs
[
-
1
]
if
dirs
and
not
dirs
[
0
]:
dirs
=
dirs
[
1
:]
user
=
passwd
=
''
# XXX
try
:
fw
=
self
.
connect_ftp
(
user
,
passwd
,
host
,
port
,
dirs
)
type
=
file
and
'I'
or
'D'
for
attr
in
attrs
:
attr
,
value
=
splitattr
(
attr
)
if
string
.
lower
(
attr
)
==
'type'
and
\
value
in
(
'a'
,
'A'
,
'i'
,
'I'
,
'd'
,
'D'
):
type
=
string
.
upper
(
value
)
fp
,
retrlen
=
fw
.
retrfile
(
file
,
type
)
if
retrlen
is
not
None
and
retrlen
>=
0
:
sf
=
StringIO
(
'Content-Length: %d
\
n
'
%
retrlen
)
headers
=
mimetools
.
Message
(
sf
)
else
:
headers
=
noheaders
()
return
addinfourl
(
fp
,
headers
,
req
.
get_full_url
())
except
ftplib
.
all_errors
,
msg
:
raise
IOError
,
(
'ftp error'
,
msg
),
sys
.
exc_info
()[
2
]
def
connect_ftp
(
self
,
user
,
passwd
,
host
,
port
,
dirs
):
fw
=
ftpwrapper
(
user
,
passwd
,
host
,
port
,
dirs
)
...
...
@@ -901,13 +901,13 @@ class CacheFTPHandler(FTPHandler):
self
.
timeout
=
{}
self
.
soonest
=
0
self
.
delay
=
60
self
.
max_conns
=
16
self
.
max_conns
=
16
def
setTimeout
(
self
,
t
):
self
.
delay
=
t
def
setMaxConns
(
self
,
m
):
self
.
max_conns
=
m
self
.
max_conns
=
m
def
connect_ftp
(
self
,
user
,
passwd
,
host
,
port
,
dirs
):
key
=
user
,
passwd
,
host
,
port
...
...
@@ -916,11 +916,11 @@ class CacheFTPHandler(FTPHandler):
else
:
self
.
cache
[
key
]
=
ftpwrapper
(
user
,
passwd
,
host
,
port
,
dirs
)
self
.
timeout
[
key
]
=
time
.
time
()
+
self
.
delay
self
.
check_cache
()
self
.
check_cache
()
return
self
.
cache
[
key
]
def
check_cache
(
self
):
# first check for old ones
# first check for old ones
t
=
time
.
time
()
if
self
.
soonest
<=
t
:
for
k
,
v
in
self
.
timeout
.
items
():
...
...
@@ -931,56 +931,56 @@ class CacheFTPHandler(FTPHandler):
self
.
soonest
=
min
(
self
.
timeout
.
values
())
# then check the size
if
len
(
self
.
cache
)
==
self
.
max_conns
:
for
k
,
v
in
self
.
timeout
.
items
():
if
v
==
self
.
soonest
:
del
self
.
cache
[
k
]
del
self
.
timeout
[
k
]
break
self
.
soonest
=
min
(
self
.
timeout
.
values
())
if
len
(
self
.
cache
)
==
self
.
max_conns
:
for
k
,
v
in
self
.
timeout
.
items
():
if
v
==
self
.
soonest
:
del
self
.
cache
[
k
]
del
self
.
timeout
[
k
]
break
self
.
soonest
=
min
(
self
.
timeout
.
values
())
class
GopherHandler
(
BaseHandler
):
def
gopher_open
(
self
,
req
):
host
=
req
.
get_host
()
if
not
host
:
raise
GopherError
(
'no host given'
)
host
=
unquote
(
host
)
selector
=
req
.
get_selector
()
type
,
selector
=
splitgophertype
(
selector
)
selector
,
query
=
splitquery
(
selector
)
selector
=
unquote
(
selector
)
if
query
:
query
=
unquote
(
query
)
fp
=
gopherlib
.
send_query
(
selector
,
query
,
host
)
else
:
fp
=
gopherlib
.
send_selector
(
selector
,
host
)
return
addinfourl
(
fp
,
noheaders
(),
req
.
get_full_url
())
host
=
req
.
get_host
()
if
not
host
:
raise
GopherError
(
'no host given'
)
host
=
unquote
(
host
)
selector
=
req
.
get_selector
()
type
,
selector
=
splitgophertype
(
selector
)
selector
,
query
=
splitquery
(
selector
)
selector
=
unquote
(
selector
)
if
query
:
query
=
unquote
(
query
)
fp
=
gopherlib
.
send_query
(
selector
,
query
,
host
)
else
:
fp
=
gopherlib
.
send_selector
(
selector
,
host
)
return
addinfourl
(
fp
,
noheaders
(),
req
.
get_full_url
())
#bleck! don't use this yet
class
OpenerFactory
:
default_handlers
=
[
UnknownHandler
,
HTTPHandler
,
HTTPDefaultErrorHandler
,
HTTPRedirectHandler
,
FTPHandler
,
FileHandler
]
HTTPDefaultErrorHandler
,
HTTPRedirectHandler
,
FTPHandler
,
FileHandler
]
proxy_handlers
=
[
ProxyHandler
]
handlers
=
[]
replacement_handlers
=
[]
def
add_proxy_handler
(
self
,
ph
):
self
.
proxy_handlers
=
self
.
proxy_handlers
+
[
ph
]
self
.
proxy_handlers
=
self
.
proxy_handlers
+
[
ph
]
def
add_handler
(
self
,
h
):
self
.
handlers
=
self
.
handlers
+
[
h
]
self
.
handlers
=
self
.
handlers
+
[
h
]
def
replace_handler
(
self
,
h
):
pass
pass
def
build_opener
(
self
):
opener
=
OpenerDirectory
()
for
ph
in
self
.
proxy_handlers
:
if
type
(
ph
)
==
types
.
ClassType
:
ph
=
ph
()
opener
.
add_handler
(
ph
)
opener
=
OpenerDirectory
()
for
ph
in
self
.
proxy_handlers
:
if
type
(
ph
)
==
types
.
ClassType
:
ph
=
ph
()
opener
.
add_handler
(
ph
)
if
__name__
==
"__main__"
:
# XXX some of the test code depends on machine configurations that
...
...
@@ -993,24 +993,24 @@ if __name__ == "__main__":
else
:
localhost
=
None
urls
=
[
# Thanks to Fred for finding these!
'gopher://gopher.lib.ncsu.edu/11/library/stacks/Alex'
,
'gopher://gopher.vt.edu:10010/10/33'
,
# Thanks to Fred for finding these!
'gopher://gopher.lib.ncsu.edu/11/library/stacks/Alex'
,
'gopher://gopher.vt.edu:10010/10/33'
,
'file:/etc/passwd'
,
'file://nonsensename/etc/passwd'
,
'ftp://www.python.org/pub/tmp/httplib.py'
,
'file:/etc/passwd'
,
'file://nonsensename/etc/passwd'
,
'ftp://www.python.org/pub/tmp/httplib.py'
,
'ftp://www.python.org/pub/tmp/imageop.c'
,
'ftp://www.python.org/pub/tmp/blat'
,
'http://www.espn.com/'
,
# redirect
'http://www.python.org/Spanish/Inquistion/'
,
(
'http://grail.cnri.reston.va.us/cgi-bin/faqw.py'
,
'query=pythonistas&querytype=simple&casefold=yes&req=search'
),
'http://www.python.org/'
,
'http://www.espn.com/'
,
# redirect
'http://www.python.org/Spanish/Inquistion/'
,
(
'http://grail.cnri.reston.va.us/cgi-bin/faqw.py'
,
'query=pythonistas&querytype=simple&casefold=yes&req=search'
),
'http://www.python.org/'
,
'ftp://prep.ai.mit.edu/welcome.msg'
,
'ftp://www.python.org/pub/tmp/figure.prn'
,
'ftp://www.python.org/pub/tmp/interp.pl'
,
'http://checkproxy.cnri.reston.va.us/test/test.html'
,
'http://checkproxy.cnri.reston.va.us/test/test.html'
,
]
if
localhost
is
not
None
:
...
...
@@ -1034,10 +1034,10 @@ if __name__ == "__main__":
# XXX try out some custom proxy objects too!
def
at_cnri
(
req
):
host
=
req
.
get_host
()
print
host
if
host
[
-
18
:]
==
'.cnri.reston.va.us'
:
return
1
host
=
req
.
get_host
()
print
host
if
host
[
-
18
:]
==
'.cnri.reston.va.us'
:
return
1
p
=
CustomProxy
(
'http'
,
at_cnri
,
'proxy.cnri.reston.va.us'
)
ph
=
CustomProxyHandler
(
p
)
...
...
@@ -1052,9 +1052,9 @@ if __name__ == "__main__":
try
:
f
=
urlopen
(
url
,
req
)
except
IOError
,
err
:
print
"IOError:"
,
err
except
socket
.
error
,
err
:
print
"socket.error:"
,
err
print
"IOError:"
,
err
except
socket
.
error
,
err
:
print
"socket.error:"
,
err
else
:
buf
=
f
.
read
()
f
.
close
()
...
...
Lib/whichdb.py
View file @
13a2c279
...
...
@@ -56,7 +56,7 @@ def whichdb(filename):
# BSD hash v2 has a 12-byte NULL pad in front of the file type
try
:
(
magic
,)
=
struct
.
unpack
(
"=l"
,
s16
[
-
4
:])
(
magic
,)
=
struct
.
unpack
(
"=l"
,
s16
[
-
4
:])
except
struct
.
error
:
return
""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment