+#!/usr/bin/env python
+# encoding: utf-8
"""
USAGE:
leave remove the specified user from your following list
public get latest public tweets
replies get latest replies
- search searchtwitter (Beware: octothorpe, escape it)
+ search search twitter (Beware: octothorpe, escape it)
set set your twitter status
shell login the twitter shell
import webbrowser
from api import Twitter, TwitterError
-from oauth import OAuth
+from oauth import OAuth, write_token_file, read_token_file
+from oauth_dance import oauth_dance
import ansi
OPTIONS = {
def parse_args(args, options):
long_opts = ['help', 'format=', 'refresh', 'oauth=',
- 'refresh-rate=', 'config=', 'length=', 'timestamp',
+ 'refresh-rate=', 'config=', 'length=', 'timestamp',
'datestamp', 'no-ssl']
short_opts = "e:p:f:h?rR:c:l:td"
- opts, extra_args = getopt(args, short_opts, long_opts)
+ opts, extra_args = getopt(args, short_opts, long_opts)
for opt, arg in opts:
if opt in ('-f', '--format'):
return time.strftime("%H:%M:%S ", t)
elif datestamp:
return time.strftime("%Y-%m-%d ", t)
- return ""
+ return ""
class StatusFormatter(object):
def __call__(self, status, options):
ansi.cmdColour(colour), result['from_user'],
ansi.cmdReset(), result['text']))
+_term_encoding = None
+def get_term_encoding():
+ global _term_encoding
+ if not _term_encoding:
+ lang = os.getenv('LANG', 'unknown.UTF-8').split('.')
+ if lang[1:]:
+ _term_encoding = lang[1]
+ else:
+ _term_encoding = 'UTF-8'
+ return _term_encoding
+
formatters = {}
status_formatters = {
'default': StatusFormatter,
def __call__(self, twitter, options):
raise NoSuchActionError("No such action: %s" %(options['action']))
-def printNicely(string):
+def printNicely(string):
if sys.stdout.encoding:
print string.encode(sys.stdout.encoding, 'replace')
else:
# We need to be pointing at search.twitter.com to work, and it is less
# tangly to do it here than in the main()
twitter.domain="search.twitter.com"
+ twitter.uriparts=()
# We need to bypass the TwitterCall parameter encoding, so we
# don't encode the plus sign, so we have to encode it ourselves
- query_string = "+".join([quote(term) for term in options['extra_args']])
- twitter.encoded_args = "q=%s" %(query_string)
+ query_string = "+".join(
+ [quote(term.decode(get_term_encoding()))
+ for term in options['extra_args']])
- results = twitter.search()['results']
+ results = twitter.search(q=query_string)['results']
f = get_formatter('search', options)
for result in results:
resultStr = f(result, options)
class SetStatusAction(Action):
def __call__(self, twitter, options):
- statusTxt = (u" ".join(options['extra_args'])
+ statusTxt = (" ".join(options['extra_args']).decode(get_term_encoding())
if options['extra_args']
else unicode(raw_input("message: ")))
status = (statusTxt.encode('utf8', 'replace'))
def __call__(self, twitter, options):
pass
-def parse_oauth_tokens(result):
- for r in result.split('&'):
- k, v = r.split('=')
- if k == 'oauth_token':
- oauth_token = v
- elif k == 'oauth_token_secret':
- oauth_token_secret = v
- return oauth_token, oauth_token_secret
-
-def oauth_dance(options):
- print ("Hi there! We're gonna get you all set up to use Twitter"
- " on the command-line.")
- twitter = Twitter(
- auth=OAuth('', '', CONSUMER_KEY, CONSUMER_SECRET),
- format='')
- oauth_token, oauth_token_secret = parse_oauth_tokens(
- twitter.oauth.request_token())
- print """
-In the web browser window that opens please choose to Allow access to the
-command-line tool. Copy the PIN number that appears on the next page and
-paste or type it here:
-"""
- webbrowser.open(
- 'http://api.twitter.com/oauth/authorize?oauth_token=' +
- oauth_token)
- oauth_verifier = raw_input("Please type the PIN: ").strip()
- twitter = Twitter(
- auth=OAuth(
- oauth_token, oauth_token_secret, CONSUMER_KEY, CONSUMER_SECRET),
- format='')
- oauth_token, oauth_token_secret = parse_oauth_tokens(
- twitter.oauth.access_token(oauth_verifier=oauth_verifier))
- oauth_file = open(options['oauth_filename'], 'w')
- print >> oauth_file, oauth_token
- print >> oauth_file, oauth_token_secret
- oauth_file.close()
- print "That's it! Your authorization keys have been written to %s." % (
- options['oauth_filename'])
-
-
actions = {
'authorize' : DoNothingAction,
'follow' : FollowAction,
options[option] = cp.get('twitter', option)
return options
-def read_oauth_file(fn):
- f = open(fn)
- return f.readline().strip(), f.readline().strip()
-
def main(args=sys.argv[1:]):
arg_options = {}
try:
print >> sys.stderr
raise SystemExit(1)
- config_options = loadConfig(
+ config_path = os.path.expanduser(
arg_options.get('config_filename') or OPTIONS.get('config_filename'))
+ config_options = loadConfig(config_path)
# Apply the various options in order, the most important applied last.
# Defaults first, then what's read from config file, then command-line
print >> sys.stderr, "Use 'twitter -h' for help."
return 1
+ oauth_filename = os.path.expanduser(options['oauth_filename'])
+
if (options['action'] == 'authorize'
- or not os.path.exists(options['oauth_filename'])):
- oauth_dance(options)
+ or not os.path.exists(oauth_filename)):
+ oauth_dance(
+ "the Command-Line Tool", CONSUMER_KEY, CONSUMER_SECRET,
+ options['oauth_filename'])
+
+ oauth_token, oauth_token_secret = read_token_file(oauth_filename)
- oauth_token, oauth_token_secret = read_oauth_file(options['oauth_filename'])
-
twitter = Twitter(
auth=OAuth(
oauth_token, oauth_token_secret, CONSUMER_KEY, CONSUMER_SECRET),
- secure=options['secure'])
+ secure=options['secure'],
+ api_version='1',
+ domain='api.twitter.com')
try:
Action()(twitter, options)
print >>sys.stderr, e
raise SystemExit(1)
except TwitterError, e:
- print >> sys.stderr, e.args[0]
+ print >> sys.stderr, str(e)
print >> sys.stderr, "Use 'twitter -h' for help."
raise SystemExit(1)