#!/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()