Skip to content

Commit 8077379

Browse files
committed
Adding the mechanize python code
1 parent 488ac5d commit 8077379

29 files changed

+14363
-0
lines changed

mechanize/__init__.py

Lines changed: 211 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,211 @@
1+
__all__ = [
2+
'AbstractBasicAuthHandler',
3+
'AbstractDigestAuthHandler',
4+
'BaseHandler',
5+
'Browser',
6+
'BrowserStateError',
7+
'CacheFTPHandler',
8+
'ContentTooShortError',
9+
'Cookie',
10+
'CookieJar',
11+
'CookiePolicy',
12+
'DefaultCookiePolicy',
13+
'DefaultFactory',
14+
'FTPHandler',
15+
'Factory',
16+
'FileCookieJar',
17+
'FileHandler',
18+
'FormNotFoundError',
19+
'FormsFactory',
20+
'HTTPBasicAuthHandler',
21+
'HTTPCookieProcessor',
22+
'HTTPDefaultErrorHandler',
23+
'HTTPDigestAuthHandler',
24+
'HTTPEquivProcessor',
25+
'HTTPError',
26+
'HTTPErrorProcessor',
27+
'HTTPHandler',
28+
'HTTPPasswordMgr',
29+
'HTTPPasswordMgrWithDefaultRealm',
30+
'HTTPProxyPasswordMgr',
31+
'HTTPRedirectDebugProcessor',
32+
'HTTPRedirectHandler',
33+
'HTTPRefererProcessor',
34+
'HTTPRefreshProcessor',
35+
'HTTPResponseDebugProcessor',
36+
'HTTPRobotRulesProcessor',
37+
'HTTPSClientCertMgr',
38+
'HeadParser',
39+
'History',
40+
'LWPCookieJar',
41+
'Link',
42+
'LinkNotFoundError',
43+
'LinksFactory',
44+
'LoadError',
45+
'MSIECookieJar',
46+
'MozillaCookieJar',
47+
'OpenerDirector',
48+
'OpenerFactory',
49+
'ParseError',
50+
'ProxyBasicAuthHandler',
51+
'ProxyDigestAuthHandler',
52+
'ProxyHandler',
53+
'Request',
54+
'RobotExclusionError',
55+
'RobustFactory',
56+
'RobustFormsFactory',
57+
'RobustLinksFactory',
58+
'RobustTitleFactory',
59+
'SeekableResponseOpener',
60+
'TitleFactory',
61+
'URLError',
62+
'USE_BARE_EXCEPT',
63+
'UnknownHandler',
64+
'UserAgent',
65+
'UserAgentBase',
66+
'XHTMLCompatibleHeadParser',
67+
'__version__',
68+
'build_opener',
69+
'install_opener',
70+
'lwp_cookie_str',
71+
'make_response',
72+
'request_host',
73+
'response_seek_wrapper', # XXX deprecate in public interface?
74+
'seek_wrapped_response', # XXX should probably use this internally in place of response_seek_wrapper()
75+
'str2time',
76+
'urlopen',
77+
'urlretrieve',
78+
'urljoin',
79+
80+
# ClientForm API
81+
'AmbiguityError',
82+
'ControlNotFoundError',
83+
'FormParser',
84+
'ItemCountError',
85+
'ItemNotFoundError',
86+
'LocateError',
87+
'Missing',
88+
'ParseFile',
89+
'ParseFileEx',
90+
'ParseResponse',
91+
'ParseResponseEx',
92+
'ParseString',
93+
'XHTMLCompatibleFormParser',
94+
# deprecated
95+
'CheckboxControl',
96+
'Control',
97+
'FileControl',
98+
'HTMLForm',
99+
'HiddenControl',
100+
'IgnoreControl',
101+
'ImageControl',
102+
'IsindexControl',
103+
'Item',
104+
'Label',
105+
'ListControl',
106+
'PasswordControl',
107+
'RadioControl',
108+
'ScalarControl',
109+
'SelectControl',
110+
'SubmitButtonControl',
111+
'SubmitControl',
112+
'TextControl',
113+
'TextareaControl',
114+
]
115+
116+
import logging
117+
import sys
118+
119+
from _version import __version__
120+
121+
# high-level stateful browser-style interface
122+
from _mechanize import \
123+
Browser, History, \
124+
BrowserStateError, LinkNotFoundError, FormNotFoundError
125+
126+
# configurable URL-opener interface
127+
from _useragent import UserAgentBase, UserAgent
128+
from _html import \
129+
Link, \
130+
Factory, DefaultFactory, RobustFactory, \
131+
FormsFactory, LinksFactory, TitleFactory, \
132+
RobustFormsFactory, RobustLinksFactory, RobustTitleFactory
133+
134+
# urllib2 work-alike interface. This is a superset of the urllib2 interface.
135+
from _urllib2 import *
136+
import _urllib2
137+
if hasattr(_urllib2, "HTTPSHandler"):
138+
__all__.append("HTTPSHandler")
139+
del _urllib2
140+
141+
# misc
142+
from _http import HeadParser
143+
from _http import XHTMLCompatibleHeadParser
144+
from _opener import ContentTooShortError, OpenerFactory, urlretrieve
145+
from _response import \
146+
response_seek_wrapper, seek_wrapped_response, make_response
147+
from _rfc3986 import urljoin
148+
from _util import http2time as str2time
149+
150+
# cookies
151+
from _clientcookie import Cookie, CookiePolicy, DefaultCookiePolicy, \
152+
CookieJar, FileCookieJar, LoadError, request_host_lc as request_host, \
153+
effective_request_host
154+
from _lwpcookiejar import LWPCookieJar, lwp_cookie_str
155+
# 2.4 raises SyntaxError due to generator / try/finally use
156+
if sys.version_info[:2] > (2,4):
157+
try:
158+
import sqlite3
159+
except ImportError:
160+
pass
161+
else:
162+
from _firefox3cookiejar import Firefox3CookieJar
163+
from _mozillacookiejar import MozillaCookieJar
164+
from _msiecookiejar import MSIECookieJar
165+
166+
# forms
167+
from _form import (
168+
AmbiguityError,
169+
ControlNotFoundError,
170+
FormParser,
171+
ItemCountError,
172+
ItemNotFoundError,
173+
LocateError,
174+
Missing,
175+
ParseError,
176+
ParseFile,
177+
ParseFileEx,
178+
ParseResponse,
179+
ParseResponseEx,
180+
ParseString,
181+
XHTMLCompatibleFormParser,
182+
# deprecated
183+
CheckboxControl,
184+
Control,
185+
FileControl,
186+
HTMLForm,
187+
HiddenControl,
188+
IgnoreControl,
189+
ImageControl,
190+
IsindexControl,
191+
Item,
192+
Label,
193+
ListControl,
194+
PasswordControl,
195+
RadioControl,
196+
ScalarControl,
197+
SelectControl,
198+
SubmitButtonControl,
199+
SubmitControl,
200+
TextControl,
201+
TextareaControl,
202+
)
203+
204+
# If you hate the idea of turning bugs into warnings, do:
205+
# import mechanize; mechanize.USE_BARE_EXCEPT = False
206+
USE_BARE_EXCEPT = True
207+
208+
logger = logging.getLogger("mechanize")
209+
if logger.level is logging.NOTSET:
210+
logger.setLevel(logging.CRITICAL)
211+
del logger

mechanize/_auth.py

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
"""HTTP Authentication and Proxy support.
2+
3+
4+
Copyright 2006 John J. Lee <jjl@pobox.com>
5+
6+
This code is free software; you can redistribute it and/or modify it under
7+
the terms of the BSD or ZPL 2.1 licenses (see the file COPYING.txt
8+
included with the distribution).
9+
10+
"""
11+
12+
from _urllib2_fork import HTTPPasswordMgr
13+
14+
15+
# TODO: stop deriving from HTTPPasswordMgr
16+
class HTTPProxyPasswordMgr(HTTPPasswordMgr):
17+
# has default realm and host/port
18+
def add_password(self, realm, uri, user, passwd):
19+
# uri could be a single URI or a sequence
20+
if uri is None or isinstance(uri, basestring):
21+
uris = [uri]
22+
else:
23+
uris = uri
24+
passwd_by_domain = self.passwd.setdefault(realm, {})
25+
for uri in uris:
26+
for default_port in True, False:
27+
reduced_uri = self.reduce_uri(uri, default_port)
28+
passwd_by_domain[reduced_uri] = (user, passwd)
29+
30+
def find_user_password(self, realm, authuri):
31+
attempts = [(realm, authuri), (None, authuri)]
32+
# bleh, want default realm to take precedence over default
33+
# URI/authority, hence this outer loop
34+
for default_uri in False, True:
35+
for realm, authuri in attempts:
36+
authinfo_by_domain = self.passwd.get(realm, {})
37+
for default_port in True, False:
38+
reduced_authuri = self.reduce_uri(authuri, default_port)
39+
for uri, authinfo in authinfo_by_domain.iteritems():
40+
if uri is None and not default_uri:
41+
continue
42+
if self.is_suburi(uri, reduced_authuri):
43+
return authinfo
44+
user, password = None, None
45+
46+
if user is not None:
47+
break
48+
return user, password
49+
50+
def reduce_uri(self, uri, default_port=True):
51+
if uri is None:
52+
return None
53+
return HTTPPasswordMgr.reduce_uri(self, uri, default_port)
54+
55+
def is_suburi(self, base, test):
56+
if base is None:
57+
# default to the proxy's host/port
58+
hostport, path = test
59+
base = (hostport, "/")
60+
return HTTPPasswordMgr.is_suburi(self, base, test)
61+
62+
63+
class HTTPSClientCertMgr(HTTPPasswordMgr):
64+
# implementation inheritance: this is not a proper subclass
65+
def add_key_cert(self, uri, key_file, cert_file):
66+
self.add_password(None, uri, key_file, cert_file)
67+
def find_key_cert(self, authuri):
68+
return HTTPPasswordMgr.find_user_password(self, None, authuri)

0 commit comments

Comments
 (0)