#!/usr/bin/python
import getopt, sys, httplib, string, re, getpass
def usage():
print "%s -p (--post-entry) <file>" % (sys.argv[0])
def extract_pass(header):
'''
Grab encrypted password from a "Set-Cookie" header.
Example header:
"Set-Cookie: id=jordan:32f/XCcPSGAMzsS5/ky/; path=/; Expires=Monday"
Result:
"32f/XCcPSGAMzsS5/ky/"
'''
# Grab the Set-Cookie: line.
header = string.split(header, '\n')[2]
return string.split(string.split(header, ':')[2], ';')[0]
def check_response(code, header):
'''
Check if HTTP headers were accepted by server.
'''
if code != 200:
print 'Error sending headers -- %s' % (header)
sys.exit()
def check_auth(header):
'''
Check if authentication failed.
'''
# Bad login or password.
if string.find(header, 'Set-Cookie') == -1:
print 'Error authenticating -- %s' % (header)
sys.exit()
def extract_entry_number(html):
'''
Return the diary entry number from raw HTML code.
'''
# Find the line 'name=key value=N' where N is
# the diary entry number and save it.
entry_num = ''
for line in html:
if string.find(line, 'name=key value=') != -1:
# Extract the number from the string
entry_num = re.sub('\D', '', line)
break
return entry_num
def get_entry_number(userid, password):
'''
Get the diary entry number for "userid." This number is
necessary in order to post new diary entries.
'''
hlink = httplib.HTTP('www.advogato.org')
hlink.putrequest('GET', '/diary/ HTTP/1.0')
hlink.putheader('Host', 'www.advogato.org')
hlink.putheader('Cookie2', '$Version="1"')
hlink.putheader('Cookie', 'id=%s:%s' % (userid, password))
hlink.endheaders()
errcode, errmsg, header = hlink.getreply()
check_response(errcode, header)
# Grab HTML.
raw_html = string.split(hlink.getfile().read(), '\n')
hlink.getfile().close()
entry_num = ''
entry_num = extract_entry_number(raw_html)
if not entry_num:
print 'Entry value for %s not found -- %s' % (userid, header)
sys.exit()
return entry_num
def get_entry(entry_file):
'''
Return the contents of `entry_file`, which contains
the user`s entry.
'''
try:
file_in = open(entry_file, 'r')
except:
print 'Error opening %s' % (entry_file)
sys.exit()
# Replace newlines with
's, otherwise the encoded URL
# will not be accepted.
entry = re.sub('\n', '
', file_in.read())
return entry
def post_entry(user_info, entry_file):
'''
Post entry to advogato.
'''
userid = user_info[0]
password = user_info[1]
urlencoded = 'u=' + userid + '&pass=' + password
hlink = httplib.HTTP('www.advogato.org')
hlink.putrequest('POST', '/acct/loginsub.html HTTP/1.0')
hlink.putheader('Host', 'www.advogato.org')
hlink.putheader('Content-type', 'application/x-www-form-urlencoded')
hlink.putheader('Content-length', '%d\n\n%s' % (len(urlencoded),
urlencoded))
hlink.endheaders()
errcode, errmsg, header = hlink.getreply()
# Error response from server (to make sure our requests went
# through) and user information.
check_response(errcode, header)
check_auth(str(header))
# Extract the encrypted password from header.
password = extract_pass(str(header))
entry_num = get_entry_number(userid, password)
content = get_entry(entry_file)
entry = 'entry=' + content + '&post=Post&key=' + str(entry_num)
hlink = httplib.HTTP('www.advogato.org')
hlink.putrequest('POST', '/diary/post.html HTTP/1.0')
hlink.putheader('Host', 'www.advogato.org')
hlink.putheader('Cookie2', '$Version="1"')
hlink.putheader('Cookie', 'id=%s:%s' % (userid, password))
hlink.putheader('Content-type', 'application/x-www-form-urlencoded')
hlink.putheader('Content-length', '%d\n\n%s' % (len(entry), entry))
hlink.endheaders()
errcode, errmsg, header = hlink.getreply()
check_response(errcode, header)
print 'Entry \'%s\' posted successfully.' % (entry_file)
def get_user_info():
'''
Return the user`s advogato username and password.
'''
userid = raw_input('Enter your advogato username: ')
password = getpass.getpass('password: ')
print '\n'
return [userid, password]
def main():
output = None
try:
opts, args = getopt.getopt(sys.argv[1:], "p:", ["post-entry="])
except:
usage()
sys.exit()
for option, argument in opts:
# Post an entry.
if option in ("-p", "--post-entry"):
output = argument
user_info = get_user_info()
post_entry(user_info, argument)
break # Because it's the only option right now.
if not output:
usage()
sys.exit()
if __name__ == "__main__":
main()