~chris.lasher/emptytwits/trunk

« back to all changes in this revision

Viewing changes to emptytwits.py

  • Committer: Chris Lasher
  • Date: 2008-12-06 20:53:34 UTC
  • Revision ID: chris.lasher@gmail.com-20081206205334-kqzt4edjhzy4b7yh
Starting emptytwits project.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
# -*- coding: UTF-8 -*-
 
3
 
 
4
"""
 
5
A small script for discovering Twitter users you follow who never
 
6
actually tweet.
 
7
 
 
8
"""
 
9
 
 
10
# for @berci
 
11
 
 
12
__author__ = 'Chris Lasher'
 
13
__email__ = 'chris DOT lasher <AT> gmail DOT com'
 
14
 
 
15
import ConfigParser
 
16
import optparse
 
17
import os
 
18
import sys
 
19
# Requires python-twitter
 
20
# see http://code.google.com/p/python-twitter/
 
21
import twitter
 
22
 
 
23
 
 
24
# Configuration file name
 
25
RC_FILE = '.emptytwitsrc'
 
26
# By default, this program will look under the user's home directory for
 
27
# a configuration
 
28
RC_PATH = os.path.expanduser('~') + os.sep + RC_FILE
 
29
 
 
30
# The configuration file should be a file containing one section with
 
31
# two variables: username and password. For example, it should look
 
32
# something like below:
 
33
#
 
34
# [User]
 
35
# username=myusername
 
36
# password=mypassword
 
37
 
 
38
USER_SECTION = 'User'
 
39
 
 
40
 
 
41
class UserInfoError(Exception):
 
42
    """
 
43
    Error raised when there is not enough information from the user
 
44
    to obtain a handle for the API.
 
45
 
 
46
    """
 
47
 
 
48
    pass
 
49
 
 
50
 
 
51
def make_cli_parser():
 
52
 
 
53
    usage = "\n\n".join([
 
54
        "python %prog [OPTIONS]",
 
55
        __doc__,
 
56
        """\
 
57
By default, checks for a configuration file containing your user name
 
58
and password, for security purposes. You can alternatively specify
 
59
your user name and password directly on the command line.
 
60
 
 
61
    python %prog -u USERNAME -p PASSWORD
 
62
 
 
63
See help for more details.
 
64
 
 
65
    python %prog -h
 
66
"""])
 
67
 
 
68
    cli_parser = optparse.OptionParser(usage)
 
69
    cli_parser.add_option('-c', '--config',
 
70
        default=RC_PATH,
 
71
        help="Specify a different path to a configuration file"
 
72
        " [default: %default]"
 
73
    )
 
74
    cli_parser.add_option('-u', '--username',
 
75
        help="Specify a user name directly"
 
76
    )
 
77
    cli_parser.add_option('-p', '--password',
 
78
        help="Specify a password directly"
 
79
    )
 
80
 
 
81
    return cli_parser
 
82
 
 
83
 
 
84
def find_non_tweeters(account, users):
 
85
    """
 
86
    Identifies Twitter users who have never tweeted.
 
87
 
 
88
    :Parameters:
 
89
    -`account`: A Twitter API instance for the user's account
 
90
    -`users`: Users of interest
 
91
 
 
92
    :Returns:
 
93
    -`non_tweeters`: a list of user instances for users who have never
 
94
        tweeted
 
95
 
 
96
    """
 
97
 
 
98
    non_tweeters = [user for user in users if not user.status]
 
99
    return non_tweeters
 
100
 
 
101
 
 
102
def get_config_username_and_password(config_file_path):
 
103
 
 
104
    if not os.path.isfile(config_file_path):
 
105
        raise IOError("%s doesn't exist or isn't readable" % (
 
106
                config_file_path))
 
107
    config = ConfigParser.ConfigParser()
 
108
    config.read(config_file_path)
 
109
    if config.has_option(USER_SECTION, 'username'):
 
110
        username = config.get(USER_SECTION, 'username')
 
111
    else:
 
112
        username = None
 
113
 
 
114
    if config.has_option(USER_SECTION, 'password'):
 
115
        password = config.get(USER_SECTION, 'password')
 
116
    else:
 
117
        password = None
 
118
 
 
119
    return username, password
 
120
 
 
121
 
 
122
def get_username_and_password(cli_opts):
 
123
    username = cli_opts.username
 
124
    password = cli_opts.password
 
125
    if not (username and password):
 
126
        config_file_path = cli_opts.config
 
127
        cfg_username, cfg_password = \
 
128
                get_config_username_and_password(config_file_path)
 
129
 
 
130
        if not username:
 
131
            username = cfg_username
 
132
        if not password:
 
133
            password = cfg_password
 
134
 
 
135
    if not (username and password):
 
136
        raise UserInfoError("Not enough information obtained.")
 
137
    else:
 
138
        return username, password
 
139
 
 
140
 
 
141
def main(argv):
 
142
    cli_parser = make_cli_parser()
 
143
    opts, args = cli_parser.parse_args(argv)
 
144
    try:
 
145
        username, password = get_username_and_password(opts)
 
146
    except IOError:
 
147
        MSG = "Configuration %s does not exist or is not readable." % (
 
148
                opts.config)
 
149
        cli_parser.error(MSG)
 
150
    except UserInfoError:
 
151
        MSG = "Not enough user information specified."
 
152
        cli_parser.error(MSG)
 
153
    account = twitter.Api(username, password)
 
154
    friends = account.GetFriends()
 
155
    non_tweeters = find_non_tweeters(account, friends)
 
156
    for friend in non_tweeters:
 
157
        print friend.screen_name
 
158
 
 
159
 
 
160
if __name__ == '__main__':
 
161
    main(sys.argv[1:])