forked from anka-213/fuckeveryword
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Adam Parrish
committed
Nov 15, 2012
0 parents
commit 11f5c15
Showing
3 changed files
with
157 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
Copyright (c) 2012 Adam Parrish | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy of | ||
this software and associated documentation files (the "Software"), to deal in | ||
the Software without restriction, including without limitation the rights to | ||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies | ||
of the Software, and to permit persons to whom the Software is furnished to do | ||
so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
Everyword Bot | ||
------------- | ||
|
||
This is a small Python script that implements an [`@everyword`](http://twitter.com/everyword)-like Twitter bot. Here's what you'll need to run it: | ||
|
||
* Python 2.6+ | ||
* [tweepy](http://tweepy.github.com/) | ||
* a plain text file, with each of your desired tweets on one line | ||
|
||
Instructions | ||
------------ | ||
|
||
Run the script from the command-line like so: | ||
|
||
$ python everywordbot.py --consumer_key=<ckey> --consumer_secret=<csecret> \ | ||
--access_token=<atoken> --token_secret=<tokensecret> \ | ||
--source_file=<source> --index_file=<index> | ||
|
||
... where: | ||
|
||
* `<ckey>` is your Twitter consumer key; | ||
* `<csecret>` is your Twitter consumer secret; | ||
* `<atoken>` is a valid Twitter access token; | ||
* `<tokensecret>` is the access token secret for the token given above; | ||
* `<source>` is the filename of a plain text file, with one tweet per line (defaults to `tweet_list.txt` in the current directory); and | ||
* `<index>` is the name of a file where the script can store the current tweet index (i.e., which line in the file should be tweeted next). The script must be able to write to this file. | ||
|
||
You'll need to arrange to have this script run at some interval, using a tool | ||
like `cron`. For example, to post a tweet every half hour, you might put the | ||
command line above in a bash script named `/home/aparrish/post_tweet.sh` and | ||
then put the following in your crontab: | ||
|
||
0,30 * * * * cd /home/aparrish; bash post_tweet.sh >>error.log 2>&1 | ||
|
||
Production Notes | ||
---------------- | ||
|
||
Twitter may return one of a variety of error messages in response to an attempt to post | ||
a status update (invalid authorization credentials, rate limits, fail whales, | ||
etc.). This script does not attempt to catch or differentiate between these | ||
errors; however, it will *only* increment the index if the post succeeds. (The idea is | ||
that 100% coverage of the source file is more important than 100% uptime.) | ||
|
||
As stated in the license, this software is provided under no warranty of any kind. However, if the operation of this script is critical to your business, grant application, | ||
art school thesis, or innovative government program, you may want to monitor the results of the script by (e.g.) checking | ||
the return value of the script and sending an e-mail message if it's non-zero. | ||
Feel free to update the script to handle errors in whatever | ||
method is appropriate for your specific application. | ||
|
||
Obtaining Twitter authorization credentials | ||
------------------------------------------- | ||
|
||
The easiest way to obtain the appropriate credentials is as follows: | ||
|
||
* Create a new Twitter account. This is the account on whose behalf the script will post tweets. | ||
* Go to the [Twitter Developers Site](https://dev.twitter.com/) and sign in with the account you just created. (You'll need to verify your account's e-mail address before Twitter will let you log in with your new account.) | ||
* After signing in, select "My Applications" from the drop-down in the upper-right corner of the page. | ||
* Select "Create a new application." | ||
* Fill in the form. The "Callback URL" field is not important. | ||
* You'll be taken to the overview page for your new application. Activate the "Settings" tab and change the "Application Type" from "Read only" to "Read and Write." | ||
* Return to the "Details" tab. Select "Create my access token" at the bottom of the page. | ||
* Congratulations! All the information that you need (consumer key, consumer secret, access token, access token secret) is now displayed on the "Details" tab. | ||
|
||
In my experience, Twitter may prevent newly created accounts from posting status updates, responding to such requests with invalid authorization errors. This is likely an anti-spam measure. Wait a few minutes and try again before freaking out. | ||
|
||
(The above information above may become inaccurate if Twitter changes the | ||
layout of the "My Applications" site.) | ||
|
||
License | ||
------- | ||
|
||
Everyword Bot is provided under the MIT license. See `LICENSE.TXT` for more information. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import tweepy | ||
import sys | ||
import os | ||
|
||
class EverywordBot(object): | ||
|
||
def __init__(self, consumer_key, consumer_secret, access_token, token_secret, | ||
source_file_name, index_file_name): | ||
self.source_file_name = source_file_name | ||
self.index_file_name = index_file_name | ||
|
||
auth = tweepy.OAuthHandler(consumer_key, consumer_secret) | ||
auth.set_access_token(access_token, token_secret) | ||
self.twitter = tweepy.API(auth) | ||
|
||
def _get_current_index(self): | ||
if not(os.path.isfile(self.index_file_name)): | ||
return 0 | ||
with open(self.index_file_name) as index_fh: | ||
return int(index_fh.read().strip()) | ||
|
||
def _increment_index(self, index): | ||
with open(self.index_file_name, "w") as index_fh: | ||
index_fh.truncate() | ||
index_fh.write("%d" % (index + 1)) | ||
index_fh.close() | ||
|
||
def _get_current_line(self, index): | ||
with open(self.source_file_name) as source_fh: | ||
# read up until the desired line | ||
for i in range(index+1): | ||
status_str = source_fh.readline().strip() | ||
return status_str | ||
|
||
def post(self): | ||
index = self._get_current_index() | ||
status_str = self._get_current_line(index) | ||
self.twitter.update_status(status_str) | ||
self._increment_index(index) | ||
|
||
if __name__ == '__main__': | ||
from optparse import OptionParser | ||
parser = OptionParser() | ||
parser.add_option('--consumer_key', dest='consumer_key', | ||
help="twitter consumer key") | ||
parser.add_option('--consumer_secret', dest='consumer_secret', | ||
help="twitter consumer secret") | ||
parser.add_option('--access_token', dest='access_token', | ||
help="twitter token key") | ||
parser.add_option('--token_secret', dest='token_secret', | ||
help="twitter token secret") | ||
parser.add_option('--source_file', dest='source_file', | ||
default="tweet_list.txt", | ||
help="source file (one line per tweet)") | ||
parser.add_option('--index_file', dest='index_file', | ||
default="index", | ||
help="index file (must be able to write to this file)") | ||
(options, args) = parser.parse_args() | ||
|
||
bot = EverywordBot(options.consumer_key, options.consumer_secret, | ||
options.access_token, options.token_secret, options.source_file, | ||
options.index_file) | ||
|
||
bot.post() | ||
|