Mercurial > hg > bitsyblog
annotate bitsyblog/blogme.py @ 92:bc1753ff9b8b
i hate software
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Mon, 11 Feb 2013 13:38:10 -0800 |
parents | 3da163e44b8a |
children | 5c04cf601aba |
rev | line source |
---|---|
0
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
1 #!/usr/bin/env python |
44 | 2 """ |
3 command line blogger | |
4 """ | |
5 | |
92 | 6 import datetime |
0
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
7 import optparse |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
8 import os |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
9 import subprocess |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
10 import sys |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
11 import tempfile |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
12 import urllib2 |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
13 |
44 | 14 from ConfigParser import ConfigParser |
45 | 15 from utils import datestamp |
44 | 16 |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
17 # global variable |
44 | 18 CONFIG = '.blogme' |
0
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
19 |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
20 def tmpbuffer(editor=None): |
0
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
21 """open an editor and retreive the resulting editted buffer""" |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
22 if not editor: |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
23 editor = os.environ['EDITOR'] |
0
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
24 tmpfile = tempfile.mktemp(suffix='.txt') |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
25 cmdline = editor.split() |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
26 cmdline.append(tmpfile) |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
27 edit = subprocess.call(cmdline) |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
28 buffer = file(tmpfile).read().strip() |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
29 os.remove(tmpfile) |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
30 return buffer |
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
31 |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
32 def main(args=sys.argv[1:]): |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
33 |
44 | 34 # parse command line options |
67
894a2e76bd40
add documentation to the OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
35 parser = optparse.OptionParser(description=__doc__) |
894a2e76bd40
add documentation to the OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
36 parser.add_option('-c', '--config', |
894a2e76bd40
add documentation to the OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
37 help='configuration file to use [Default: ~/.blogme]') |
894a2e76bd40
add documentation to the OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
38 parser.add_option('-f', '--file', |
894a2e76bd40
add documentation to the OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
39 help='path to blog entries for the user; does not touch net') |
894a2e76bd40
add documentation to the OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
40 parser.add_option('-H', '--host', |
894a2e76bd40
add documentation to the OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
41 help='URL of bitsyblog instance') |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
42 parser.add_option('-u', '--user') |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
43 parser.add_option('-p', '--password') |
67
894a2e76bd40
add documentation to the OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
44 parser.add_option('--private', action='store_true', default=False, |
894a2e76bd40
add documentation to the OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
45 help='denote this blog entry as private') |
894a2e76bd40
add documentation to the OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
46 parser.add_option('--secret', action='store_true', default=False, |
894a2e76bd40
add documentation to the OptionParser
Jeff Hammel <jhammel@mozilla.com>
parents:
65
diff
changeset
|
47 help='denote this blog entry as secret') |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
48 options, args = parser.parse_args() |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
49 |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
50 # sanity check |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
51 if options.private and options.secret: |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
52 print "post can't be secret and private!" |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
53 sys.exit(1) |
0
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
54 |
45 | 55 if options.file: |
56 # get the blog | |
57 if args: | |
58 msg = ' '.join(args) | |
59 else: | |
60 msg = tmpbuffer() | |
61 options.file = os.path.join(options.file, 'entries') | |
62 for opt in 'private', 'secret': | |
63 if getattr(options, opt): | |
64 options.file = os.path.join(options.file, opt) | |
65 break | |
66 else: | |
67 options.file = os.path.join(options.file, 'public') | |
68 options.file = os.path.join(options.file, datestamp()) | |
69 f = file(options.file, 'w') | |
70 print >> f, msg | |
71 f.close() | |
77
3da163e44b8a
print the absolute path to the blog file
Jeff Hammel <jhammel@mozilla.com>
parents:
67
diff
changeset
|
72 print os.path.abspath(options.file) |
45 | 73 sys.exit(0) |
74 | |
44 | 75 # parse dotfile config |
76 config = ConfigParser() | |
45 | 77 _config = {} # config to write out |
44 | 78 if not options.config: |
79 home = os.environ['HOME'] | |
80 options.config = os.path.join(home, CONFIG) | |
81 if os.path.exists(options.config): | |
82 config.read(options.config) | |
0
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
83 |
45 | 84 # get default host, if available |
85 if options.host: | |
46
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
86 if not config.has_option('DEFAULTS', 'host'): |
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
87 _config['default'] = options.host |
45 | 88 else: |
89 if config.has_option('DEFAULTS', 'host'): | |
90 options.host = config.get('DEFAULTS', 'host') | |
91 else: | |
92 print "Enter URL of host: ", | |
46
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
93 options.host = raw_input() |
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
94 _config['default'] = options.host |
45 | 95 |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
96 # determine user name and password |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
97 fields = [ 'user', 'password' ] |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
98 for field in fields: |
46
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
99 has_option = config.has_option(options.host, field) |
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
100 |
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
101 if getattr(options, field): |
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
102 if (not has_option) or (config.get(options.host, field) != getattr(options, field)): |
45 | 103 _config[field] = getattr(options, field) |
104 else: | |
46
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
105 if has_option: |
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
106 setattr(options, field, config.get(options.host, field)) |
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
107 else: |
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
108 print "%s: " % field, |
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
109 setattr(options, field, raw_input()) |
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
110 _config[field] = getattr(options, field) |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
111 |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
112 # write the dotfile if it doesn't exist |
45 | 113 if _config: |
114 if 'default' in _config: | |
115 if not config.has_section('DEFAULTS'): | |
116 config.add_section('DEFAULTS') | |
117 config.set('DEFAULTS', 'host', options.host) | |
118 if not config.has_section(options.host): | |
119 config.add_section(options.host) | |
120 for field in fields: | |
121 if not config.has_option(options.host, field): | |
122 config.set(options.host, field, getattr(options, field)) | |
46
66bfcceea3b4
improvements to blogme....it works except for a mysterious conncection reset by peer error"
k0s <k0scist@gmail.com>
parents:
45
diff
changeset
|
123 config.write(file(options.config, 'w')) |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
124 |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
125 # get the blog |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
126 if args: |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
127 msg = ' '.join(args) |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
128 else: |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
129 msg = tmpbuffer() |
0
e3823be6a423
initial commit of bitsyblog, from https://svn.openplans.org/svn/standalone/bitsyblog/trunk/
k0s <k0scist@gmail.com>
parents:
diff
changeset
|
130 |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
131 # open the url |
44 | 132 url = options.host |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
133 url += '?auth=digest' # specify authentication method |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
134 if options.private: |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
135 url += '&privacy=private' |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
136 if options.secret: |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
137 url += '&privacy=secret' |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
138 authhandler = urllib2.HTTPDigestAuthHandler() |
45 | 139 authhandler.add_password('bitsyblog', url, options.user, options.password) |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
140 opener = urllib2.build_opener(authhandler) |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
141 urllib2.install_opener(opener) |
61 | 142 attempts = 5 |
143 for i in range(attempts): | |
144 try: | |
145 connection = urllib2.urlopen(url, data=msg) | |
146 print connection.url # print the blog post's url | |
147 break | |
92 | 148 except (urllib2.HTTPError, urllib2.URLError, socket.error), e: |
65
4e41e1084e56
better exception handling, i hope; i hate lost messages
Jeff Hammel <jhammel@mozilla.com>
parents:
61
diff
changeset
|
149 continue |
92 | 150 except: |
151 print >> sys.stderr, "An error has occured:" | |
152 print >> sys.stderr, sys.exc_info() # XXX pretty crappy | |
153 break | |
65
4e41e1084e56
better exception handling, i hope; i hate lost messages
Jeff Hammel <jhammel@mozilla.com>
parents:
61
diff
changeset
|
154 else: |
92 | 155 with file('blog-%s.txt' % datetime.datetime.now().strftime("%Y%m%d"), 'w') as f: |
156 f.write(msg) | |
65
4e41e1084e56
better exception handling, i hope; i hate lost messages
Jeff Hammel <jhammel@mozilla.com>
parents:
61
diff
changeset
|
157 print >> sys.stderr, e |
4e41e1084e56
better exception handling, i hope; i hate lost messages
Jeff Hammel <jhammel@mozilla.com>
parents:
61
diff
changeset
|
158 print msg |
43
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
159 |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
160 if __name__ == '__main__': |
8b9aa9f40fa5
moving most of blogme to its own function
k0s <k0scist@gmail.com>
parents:
42
diff
changeset
|
161 main() |