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
|
#!/usr/bin/python -S
#
# Copyright 2009 Canonical Ltd. This software is licensed under the
# GNU Affero General Public License version 3 (see the file LICENSE).
import _pythonpath
import base64
import httplib
import os
import pwd
import sys
import urllib
import webbrowser
from optparse import OptionParser
from urlparse import urljoin
from cookielib import Cookie, CookieJar
from mechanize import HTTPRobotRulesProcessor
from zope.testbrowser.browser import Browser
# Should we be able to override any of these?
AUTH_FILE = '~/.lp_auth_cookie'
PRIVATE_PASTE_HOST = 'pastebin.canonical.com'
PUBLIC_PASTE_HOST = 'pastebin.ubuntu.com'
PASTE_PATH = ''
LP_AUTH_INSTRUCTIONS = """
%s doesn't contain a valid LP authentication cookie.
Please update this file, with the 'lp' cookie value your browser sends
when visiting https://launchpad.net (while being logged in). It should
look something like this:
sd33JsfeJop3esf6joi8sldfjJoIj3dssD6isfsdweJDe6i9JIKEYK
""" % AUTH_FILE
def parse_arguments():
parser = OptionParser(usage='%prog [options] [title] < stdin')
parser.add_option('-b', '--browser',
default=False, action='store_true',
help='Open web browser to the pastebin.')
parser.add_option('-p', '--private',
default=False, action='store_true',
help='Use a private pastebin (pastebin.canonical.com).')
parser.add_option('-s', '--syntax',
default='text', type='string',
help='The syntax of the pastebin.')
parser.add_option('-f', '--file',
type='string',
help='File to pastebin instead of stdin.')
options, arguments = parser.parse_args()
if len(arguments) == 0:
parser.title = None
elif len(arguments) == 1:
parser.title = arguments[0]
else:
parser.error('Too many arguments')
# Does not return
parser.options = options
parser.arguments = arguments
return parser
def get_lp_auth_cookie(path):
"""Read the authentication file, and return a Cookie object."""
path = os.path.expanduser(path)
if not os.path.exists(path):
return None
f = open(path)
try:
cookie_value = f.readline().strip()
finally:
f.close()
return Cookie(
version=0, name='lp', value=cookie_value,
port=None, port_specified=False,
domain='login.launchpad.net', domain_specified=True,
domain_initial_dot=False, path='', path_specified=None,
secure=True, expires=None, discard=True,
comment=None, comment_url=None, rest=None, rfc2109=False)
def authenticate(browser):
"""Go through the OpenID process and authenticate."""
# First click on the page where it says we have to log in.
browser.getControl('Continue').click()
return True
def main():
parser = parse_arguments()
try:
poster = os.environ['USER']
except KeyError:
poster = pwd.getpwuid(os.getuid()).pw_name
if parser.title is None:
title = "The loser %s didn't even add a title" % poster
else:
title = parser.title
if parser.options.file:
f = open(parser.options.file)
try:
content = f.read()
finally:
f.close()
else:
content = sys.stdin.read()
form = (
('poster', poster),
('syntax', [parser.options.syntax]),
('content', content),
)
browser = Browser()
paste_host = PUBLIC_PASTE_HOST
if parser.options.private:
paste_host = PRIVATE_PASTE_HOST
# Figure out the authentication.
lp_cookie = get_lp_auth_cookie(AUTH_FILE)
if lp_cookie is None:
print LP_AUTH_INSTRUCTIONS
return
cookiejar = CookieJar()
cookiejar.set_cookie(lp_cookie)
browser.mech_browser.set_cookiejar(cookiejar)
# Remove the the check for robots.txt, since the one on
# pastebin.ubuntu.com doesn't allow us to open the page. We're not
# really a robot.
browser.mech_browser.handlers = [
handler for handler in browser.mech_browser.handlers
if not isinstance(handler, HTTPRobotRulesProcessor)]
browser.open(urljoin('https://' + paste_host, PASTE_PATH))
if parser.options.private:
# We need to authenticate before pasting.
oid_form = browser.getForm(id='openid_message')
if oid_form is not None:
authenticated = authenticate(browser)
if not authenticated:
print LP_AUTH_INSTRUCTIONS
return
for name, value in form:
browser.getControl(name=name).value = value
browser.getControl('Paste!').click()
print browser.url
if parser.options.browser:
webbrowser.open(browser.url)
if __name__ == '__main__':
main()
|