]> jfr.im git - z_archive/twitter.git/blame - twitter/cmdline.py
last minute 0.4 stuff
[z_archive/twitter.git] / twitter / cmdline.py
CommitLineData
7364ea65 1"""
5251ea48 2USAGE:
7364ea65 3
5251ea48 4 twitter [action] [options]
5
6ACTIONS:
7
8 friends get latest tweets from your friends (default action)
9 public get latest public tweets
10 set set your twitter status
11
12OPTIONS:
13
14 -e --email <email> your email to login to twitter
15 -p --password <password> your twitter password
0ea01db7 16 -r --refresh run this command forever, polling every once
17 in a while (default: every 5 minutes)
18 -R --refresh-rate <rate> set the refresh rate (in seconds)
19 -f --format <format> specify the output format for status updates
21e3bd23 20 -c --config <filename> read username and password from given config
21 file (default ~/.twitter)
0ea01db7 22
23FORMATS for the --format option
24
25 default one line per status
26 verbose multiple lines per status, more verbose status info
27 urls nothing but URLs. Dare you click them?
21e3bd23 28
29CONFIG FILES
30
31 The config file should contain your email and password like so:
32
33[twitter]
34email: <username>
35password: <password>
7364ea65 36"""
37
5251ea48 38import sys
0ea01db7 39import time
5251ea48 40from getopt import getopt
f068ff42 41from getpass import getpass
0ea01db7 42import re
21e3bd23 43import os.path
44from ConfigParser import SafeConfigParser
5251ea48 45
46from api import Twitter, TwitterError
47
48options = {
49 'email': None,
50 'password': None,
51 'action': 'friends',
0ea01db7 52 'refresh': False,
53 'refresh_rate': 600,
54 'format': 'default',
21e3bd23 55 'config_filename': os.environ.get('HOME', '') + os.sep + '.twitter',
5251ea48 56 'extra_args': []
57}
58
59def parse_args(args, options):
0ea01db7 60 long_opts = ['email', 'password', 'help', 'format', 'refresh',
21e3bd23 61 'refresh-rate', 'config']
62 short_opts = "e:p:f:h?rR:c:"
ae1d86aa 63 opts, extra_args = getopt(args, short_opts, long_opts)
5251ea48 64
65 for opt, arg in opts:
66 if opt in ('-e', '--email'):
67 options['email'] = arg
68 elif opt in ('-p', '--password'):
69 options['password'] = arg
0ea01db7 70 elif opt in ('-f', '--format'):
71 options['format'] = arg
72 elif opt in ('-r', '--refresh'):
73 options['refresh'] = True
74 elif opt in ('-R', '--refresh-rate'):
75 options['refresh_rate'] = int(arg)
5251ea48 76 elif opt in ('-?', '-h', '--help'):
77 print __doc__
78 sys.exit(0)
21e3bd23 79 elif opt in ('-c', '--config'):
80 options['config_filename'] = arg
ae1d86aa 81
82 if extra_args:
83 options['action'] = extra_args[0]
84 options['extra_args'] = extra_args[1:]
5251ea48 85
86class StatusFormatter(object):
87 def __call__(self, status):
f068ff42 88 return (u"%s %s" %(
0ea01db7 89 status['user']['screen_name'], status['text']))
5251ea48 90
f068ff42 91class VerboseStatusFormatter(object):
92 def __call__(self, status):
93 return (u"-- %s (%s) on %s\n%s\n" %(
94 status['user']['screen_name'],
95 status['user']['location'],
96 status['created_at'],
0ea01db7 97 status['text']))
f068ff42 98
0ea01db7 99class URLStatusFormatter(object):
100 urlmatch = re.compile(r'https?://\S+')
101 def __call__(self, status):
102 urls = self.urlmatch.findall(status['text'])
103 return u'\n'.join(urls) if urls else ""
104
105formatters = {
106 'default': StatusFormatter,
107 'verbose': VerboseStatusFormatter,
108 'urls': URLStatusFormatter
109}
f068ff42 110
0ea01db7 111def get_status_formatter(options):
112 sf = formatters.get(options['format'])
113 if (not sf):
114 raise TwitterError(
115 "Unknown formatter '%s'" %(options['format']))
116 return sf()
117
118class Action(object):
119 pass
120
121class NoSuchAction(Action):
122 def __call__(self, twitter, options):
123 print >> sys.stderr, "No such action: ", options['action']
124 sys.exit(1)
125
126class StatusAction(Action):
127 def __call__(self, twitter, options):
128 statuses = self.getStatuses(twitter)
129 sf = get_status_formatter(options)
130 for status in statuses:
131 statusStr = sf(status)
132 if statusStr.strip():
133 print statusStr.encode(sys.stdout.encoding, 'replace')
134
135class FriendsAction(StatusAction):
136 def getStatuses(self, twitter):
137 return reversed(twitter.statuses.friends_timeline())
5251ea48 138
0ea01db7 139class PublicAction(StatusAction):
140 def getStatuses(self, twitter):
141 return reversed(twitter.statuses.public_timeline())
142
143class SetStatusAction(Action):
144 def __call__(self, twitter, options):
772fbdd1 145 statusTxt = (u" ".join(options['extra_args'])
146 if options['extra_args']
147 else unicode(raw_input("message: ")))
148 status = (statusTxt.encode('utf8', 'replace'))
0ea01db7 149 twitter.statuses.update(status=status)
5251ea48 150
151actions = {
0ea01db7 152 'friends': FriendsAction,
153 'public': PublicAction,
154 'set': SetStatusAction,
5251ea48 155}
156
21e3bd23 157def loadConfig(filename):
158 email = None
159 password = None
160 if os.path.exists(filename):
161 cp = SafeConfigParser()
162 cp.read([filename])
163 email = cp.get('twitter', 'email', None)
164 password = cp.get('twitter', 'password', None)
165 return email, password
ae1d86aa 166
7364ea65 167def main():
ae1d86aa 168 return main_with_args(sys.argv[1:])
169
170def main_with_args(args):
5251ea48 171 parse_args(args, options)
21e3bd23 172
173 email, password = loadConfig(options['config_filename'])
174 if not options['email']: options['email'] = email
175 if not options['password']: options['password'] = password
176
0ea01db7 177 if options['refresh'] and options['action'] == 'set':
178 print >> sys.stderr, "You can't repeatedly set your status, silly"
179 print >> sys.stderr, "Use 'twitter -h' for help."
180 sys.exit(1)
f068ff42 181 if options['email'] and not options['password']:
182 options['password'] = getpass("Twitter password: ")
5251ea48 183 twitter = Twitter(options['email'], options['password'])
0ea01db7 184 action = actions.get(options['action'], NoSuchAction)()
5251ea48 185 try:
0ea01db7 186 doAction = lambda : action(twitter, options)
187 if (options['refresh']):
188 while True:
189 doAction()
190 time.sleep(options['refresh_rate'])
191 else:
192 doAction()
5251ea48 193 except TwitterError, e:
194 print >> sys.stderr, e.message
195 print >> sys.stderr, "Use 'twitter -h' for help."
196 sys.exit(1)
0ea01db7 197 except KeyboardInterrupt:
198 pass
199