tweep 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ = 0.1.0 =
2
+
3
+ * 2011-12-11 - Initial version
@@ -0,0 +1,16 @@
1
+ Copyright (c) 2011 Christophe Porteneuve
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
11
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
12
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
13
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
14
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
15
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
16
+ SOFTWARE.
@@ -0,0 +1,129 @@
1
+ Tweep - Automatic Twitter Peeping. Lets you rotate through tweets in a scheduled manner, with multiple accounts, and auto-retweet such tweets on other accounts yet. For instance, think recent accounts for product launches versus their more established company accounts.
2
+
3
+ # Installing
4
+
5
+ Tweep is in Ruby, so you need Ruby and RubyGems installed. It’s probably already there on your OSX or Linux box, and on Windows you can use the nifty [Ruby Installer](http://rubyinstaller.org/downloads/). Then just install the gem to get the `tweep` command:
6
+
7
+ ```
8
+ $ gem install tweep
9
+ ```
10
+
11
+ # Configuring your accounts
12
+
13
+ Accounts are detected by inspecting YAML files in the `accounts` subdirectory in the current working path. The base name of the file can be anything, as the actual account is identified by the authentication information inside.
14
+
15
+ To tweet on behalf of an account, Tweep needs this account’s **consumer key and secret**, along with **OAuth token and secret** for an app you setup on that account with Read/Write access (no DM access is necessary).
16
+
17
+ ## Creating custom applications for your accounts for Tweep to use
18
+
19
+ Tweep is no central application that could prompt Twitter to authorize it, otherwise open-sourcing it with its OAuth tokens would be quite problematic: any user would be able to tweet as any other!
20
+
21
+ You will need to create a custom app on your account for Tweep to use on your behalf. Here’s how:
22
+
23
+ 1. Sign in to [Twitter Developers](http://dev.twitter.com) using your regular Twitter account. This should get you to the "My Applications" screen.
24
+ 2. Click the "Create an app" link
25
+ 3. Give it a name (say, "Tweep"). This is the name that will show up as "the source" (the app you use to tweet) in your Tweep-sent tweets.
26
+ 4. description (anything) and website (your own perhaps).
27
+ 5. If you're brave and have some spare time, read the terms of use, cheekily renamed "Developer Rules of the Road." Then check the "Yes, I agree" box.
28
+ 6. Type the CAPTCHA. If it's unreadable, use the circular arrow icon on the right-hand side until you can manage it.
29
+ 7. Finally, click the "Create your Twitter application" button.
30
+
31
+ OK, almost there. Your app starts out as read-only: it won't let you *send tweets* to Twitter. You're now on the app's screen.
32
+
33
+ 8. Click the Settings tab
34
+ 9. In Application Type, choose Read and Write
35
+ 10. At the bottom of the form, click "Update this Twitter application’s settings"
36
+ 11. Get back to the Details tab, and at the bottom, click "Create my access token"
37
+
38
+ Yay, you’re done! Click the OAuth tool tab and you’ll see the 4 pieces of authentication configuration you’ll need to put in your account’s YAML file. Use the `your_account_1.yml` file as a template and copy-paste the 4 values in the proper places. Make sure you keep the values wrapped in the quotes originally placed in the YAML file.
39
+
40
+ ## Why can't I just put in my login and password?
41
+
42
+ First, because that's quite unsafe. Your password is likely one you use in a number of other places; having it lie around in some script somewhere isn't the best idea.
43
+
44
+ Second, because login and password are primarily meant for direct human use. A growing number of APIs do not allow them for program-based authentication, and Twitter's API is certainly headed that way. So OAuth it is! I realize this requires a bit of extra work on your part when setting up your access, but security and privacy are worth it.
45
+
46
+ # Scheduling your tweets
47
+
48
+ Your tweets are just a series of items in the `tweets` part of your YAML file. Use one tweet per line, surrounded by double quotes (see examples in `your_account_1.yml`). If you do need a double-quote in there, escape it by putting a backslash (`\`) before it, as you’ll see in the demo YAML file.
49
+
50
+ Then your tweet schedule uses the `schedule` key. You can provide one sub-key per day of the week, using their English lowercase name (e.g. `tuesday`). Every such key lists hours of the day when to tweet. These hours use the time zone of the machine you’ll run Tweep on. You can use 24-hour or 12-hour format for times, and Tweep uses the hour and the (optional) minute part. Seconds are overkill, so we don't want them.
51
+
52
+ In 12-hour format, you can use 'am' or 'a', 'pm' or 'p' indifferently, using whatever case (upper or lower) you like best. Also, stick to US format: `12am` is midnight, `12pm` is noon, and there is no such thing as `0am` or `0pm`…
53
+
54
+ You can use multiple hours on the same day by separating hours with commas.
55
+
56
+ If you want to schedule tweets on specific dates besides (or instead of) recurring weekdays, you can use specific dates as schedule keys, in the form `YYYY-MM-DD`, for instance `2011-12-25` for December 25, 2011.
57
+
58
+ All this is nice and well, but the way you'll schedule the running of Tweep may end up launching it a few minutes late (perhaps because other, long tasks are run before it). So you can allow a maximum delay for running Tweep, using the `allowed_delay` key in `schedule`, expressed in minutes. For instance, setting `allowed_delay: 15` will let a task scheduled as `1p` be run until 01:15pm.
59
+
60
+ # Controlling automatic retweets
61
+
62
+ To define accounts that auto-retweet your tweets, you need two things:
63
+
64
+ 1. Setup these accounts in their own files, with at minimum their authentication info so Tweep can make them retweet stuff.
65
+ 2. List these accounts as retweeters in the "source" accounts’ YAML files.
66
+
67
+ The listing part is done through the `retweeters` key, which contains one subkey per retweeter. Subkeys are named **exactly** like the YAML files for these accounts (without the `.yml` extension).
68
+
69
+ ## Retweeting every tweet
70
+
71
+ For an account to retweet *every single tweet* you write, you would use `always` as its definition. For instance, to make `mygroupie` retweet everything your `me` account tweets through Tweep, you would need the following in your `me.yml` file:
72
+
73
+ ```yaml
74
+ retweeters:
75
+ mygroupie: always
76
+ ```
77
+
78
+ This can be a bit extreme, so you may want to have such accounts retweet only every other tweet, or one tweet in three, or one in four… Just say so:
79
+
80
+ ```yaml
81
+ retweeters:
82
+ mygroupie: every 3 tweets
83
+ mysupergroupe: every other tweet
84
+ ```
85
+
86
+ We don't care about whether you actually say "tweet" or "tweets" at the end, and provide `other` as a nice-reading synonym for `2`. Should you say "every one," it'll be treated as a synonym to
87
+ "always".
88
+
89
+ # Executing your tweeting campaign
90
+
91
+ To run Tweep, just run the `tweep` command that is provided by the gem, in a directory that has the proper `accounts` subdirectory.
92
+
93
+ In order to keep track of where it stands in rotating your accounts’ tweets and observing the
94
+ "every so many tweets" policies, Tweep needs to be able to write to a `tweeping.idx` file in
95
+ the directory it’s running at.
96
+
97
+ You should then take steps to run the `tweep` command in the proper directory at regular intervals, frequently enough to honor your `schedule` settings. Linux and OSX have Crontab for this, and Windows has Scheduled Tasks.
98
+
99
+ ## Logging
100
+
101
+ By default, the `tweep` executable logs its activity (tweets and retweets) to the standard output. You can redirect this manually to a file, forsake it to `/dev/null`, or ask it to log automatically to a `tweep.log` file in the current directory by using the `--log` command-line option.
102
+
103
+ # Contributing
104
+
105
+ Tweep intends to serve a rather simple need: doing basic Twitter campaigns and making sure
106
+ your tweets get added visibility from retweets by more prominent accounts of yours until
107
+ your originally-tweeting accounts get enough followers on their own. It's more of a
108
+ product- or service-launch thing, and for the relatively short term (a few months, perhaps
109
+ up to a year?).
110
+
111
+ If you have massively complex social media needs, you’re probably better off using an online
112
+ service such as [SocialOomph](https://www.socialoomph.com/) or
113
+ [CoTweet](http://cotweet.com/).
114
+
115
+ Still, if you discover a bug, or feel you can improve the user experience in a way
116
+ consistent with the initial design goals of Tweep, just fork the project on
117
+ [Github](https://github.com/tdd/tweep), patch it, test it, and submit a pull request.
118
+ I'll be happy to check these out and merge them in if I like them!
119
+
120
+ ## Tests
121
+
122
+ I haven't written tests for this yet. I sure intend to. So stick around! And of course, contributing tests is most welcome. In order to reduce dependencies to a minimum, I will go with Test::Unit instead of fancier stuff like RSpec or Steak.
123
+
124
+ # License
125
+
126
+ Tweep is made available under the MIT license. Check the [MIT-LICENSE.txt](MIT-LICENSE.txt)
127
+ file in the soure code for details. TL;DR: as long as you keep the license in there with
128
+ due author and copyright info, you’re free to do whatever you want with Tweep, including
129
+ commercial uses. Just Don't Be Evil™.
@@ -0,0 +1,31 @@
1
+ # Auth -- this is the only required part
2
+ consumer_key: ""
3
+ consumer_secret: ""
4
+ oauth_token: ""
5
+ oauth_token_secret: ""
6
+
7
+ # Schedule -- when to chomp through the tweets.txt file in the
8
+ # same directory, tweet the top of the list, rotate and update
9
+ # the file. Optional if this is just a retweeter account.
10
+ schedule:
11
+ monday: 1pm
12
+ thursday: 1pm
13
+ 2011-12-25: 12am,12pm
14
+
15
+ tweets:
16
+ - "Blah blah blah o'blah"
17
+ - "Bleh bleh bleh bleh bleh"
18
+ - "Blih blah o'blah blouh\" bleh bleh"
19
+
20
+ # Retweets -- who retweets our tweets? You can either provide
21
+ # a single name as 'retweeter' or use the YAML array syntax inside
22
+ # a "retweeters" key. Tweep uses both if you do, "retweeter" being
23
+ # considered set to 'always'.
24
+ #
25
+ # Optional if this is just a retweeter account, that doesn't tweet on
26
+ # its own.
27
+ retweeter: porteneuve
28
+
29
+ retweeters:
30
+ porteneuve: always # Retweet every tweet.
31
+ rails: every 3 tweets
@@ -0,0 +1,6 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $LOAD_PATH.unshift(File.expand_path('../../lib', __FILE__))
4
+
5
+ require 'tweep'
6
+ Tweep.run!
@@ -0,0 +1,27 @@
1
+ #! /usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ # Tweep - Automatic Twitter Peeping
5
+ # Lets you rotate through tweets in a scheduled manner,
6
+ # with multiple accounts, and auto-retweet such tweets on other accounts yet.
7
+ #
8
+ # (c) 2011 Christophe Porteneuve
9
+
10
+ require 'tweep/account'
11
+ require 'tweep/index'
12
+ require 'tweep/logging'
13
+
14
+ module Tweep
15
+ @@index = Index.new
16
+
17
+ def self.run!
18
+ info 'Running…'
19
+ Account.each &:run!
20
+ ensure
21
+ @@index.save!
22
+ end
23
+
24
+ Dir['accounts/*.yml'].each do |defn|
25
+ Account.new(defn, @@index)
26
+ end
27
+ end
@@ -0,0 +1,67 @@
1
+ #! /usr/bin/env ruby
2
+ # encoding: utf-8
3
+ #
4
+ # (c) 2011 Christophe Porteneuve
5
+
6
+ require 'tweep/config'
7
+ require 'rubygems'
8
+ require 'twitter'
9
+
10
+ module Tweep
11
+ class Account
12
+ @@registry = {}
13
+
14
+ def self.each(&block)
15
+ @@registry.values.each(&block)
16
+ end
17
+
18
+ def self.find(nick)
19
+ @@registry[nick]
20
+ end
21
+
22
+ def initialize(yml, index)
23
+ return unless load_config(yml, index)
24
+ @index = index
25
+ @@registry[@config.nick] = self
26
+ end
27
+
28
+ def retweet!(status_id)
29
+ Tweep.info "#{@config.nick} retweets #{status_id.inspect}"
30
+ execute :retweet, status_id
31
+ end
32
+
33
+ def run!
34
+ return unless @config.has_tweets? && @config.now_is_a_good_time?
35
+ tweet!
36
+ end
37
+
38
+ private
39
+ def execute(call, *args)
40
+ Twitter.configure do |config|
41
+ @config.auth.each do |k, v|
42
+ config.send("#{k}=", v)
43
+ end
44
+ end
45
+ Twitter.send(call, *args)
46
+ end
47
+
48
+ def load_config(file, index)
49
+ return unless File.file?(file) && File.readable_real?(file)
50
+ @config = Config.new(file, index)
51
+ @config.has_auth?
52
+ end
53
+
54
+ def tweet!
55
+ status, idx = @config.next_tweet
56
+ return if status.blank?
57
+ Tweep.info "#{@config.nick} tweets: #{status}"
58
+ st = execute(:update, status)
59
+ @index.tweeted! @config.nick, idx
60
+ @config.retweeters.each do |retweeter, _|
61
+ if @config.should_get_retweeted_by?(retweeter)
62
+ self.class.find(retweeter).try(:retweet!, st.id)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,120 @@
1
+ #! /usr/bin/env ruby
2
+ # encoding: utf-8
3
+ #
4
+ # (c) 2011 Christophe Porteneuve
5
+
6
+ require 'tweep/core_exts'
7
+
8
+ module Tweep
9
+ class Config
10
+ attr_reader :auth, :nick, :schedule, :retweeters, :tweets
11
+
12
+ def initialize(file, index)
13
+ config = YAML::load(File.read(file))
14
+
15
+ @nick = File.basename(file, '.*')
16
+ @index = index
17
+
18
+ load_auth config
19
+ load_schedule config
20
+ load_retweeters config
21
+
22
+ @tweets = (config['tweets'] || []).map(&:strip)
23
+ end
24
+
25
+ def has_auth?
26
+ 4 == @auth.values.reject(&:blank?).size
27
+ end
28
+
29
+ def has_tweets?
30
+ @tweets.any?
31
+ end
32
+
33
+ def next_tweet
34
+ idx = @index.next_tweet_index(@nick)
35
+ idx = 0 if idx.to_i >= @tweets.size
36
+ [@tweets[idx], idx]
37
+ end
38
+
39
+ def now_is_a_good_time?
40
+ now = Time.now
41
+ (0..@allowed_delay.to_i).any? do |offset|
42
+ time = now - offset * 60
43
+ (@schedule[time.wday] || []).include?(time.strftime('%H:%M'))
44
+ end
45
+ end
46
+
47
+ def should_get_retweeted_by?(retweeter)
48
+ if (result = @index.retweet_timely?(@nick, retweeter))
49
+ @index.next_retweet_in! @nick, retweeter, @retweeters[retweeter]
50
+ else
51
+ @index.retweet_will_wait! @nick, retweeter
52
+ end
53
+ result
54
+ end
55
+
56
+ private
57
+ DOWS = %w(sunday monday tuesday wednesday thursday friday saturday)
58
+
59
+ TIME_REGEX = %r(
60
+ (?:
61
+ # 12-hour format - groups 1 and 2
62
+ ((?:0?[1-9]|1[012])(?::[0-5][0-9])?)
63
+ ([ap]m?)
64
+ |
65
+ # 24-hour format - group 3
66
+ ((?:[01]?[0-9]|2[0-3])(?:[0-5][0-9]?))
67
+ )
68
+ )ix
69
+
70
+ def load_auth(config)
71
+ @auth = config.slice('consumer_key', 'consumer_secret', 'oauth_token', 'oauth_token_secret')
72
+ end
73
+
74
+ def load_retweeters(config)
75
+ @retweeters = {}
76
+ if (shortcut = config['retweeter'])
77
+ @retweeters[shortcut.to_s] = 0
78
+ end
79
+ (config['retweeters'] || {}).each do |nick, pattern|
80
+ wait = 0
81
+ if pattern[/^\s*every\s+(\d+|other)(?:\s+tweets?)\s*$/i]
82
+ wait = 'other' == $1 ? 1 : [$1.to_i - 1, 0].max
83
+ end
84
+ @retweeters[nick] = wait
85
+ end
86
+ end
87
+
88
+ def load_schedule(config)
89
+ @schedule = (config['schedule'] || {}).inject({}) do |acc, (dow, hours)|
90
+ key = DOWS.index(dow.to_s.downcase)
91
+ if !key && dow.to_s[/^(\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12][0-9]|3[01])$/]
92
+ key = Date.civil($1.to_i, $2.to_i, $3.to_i) rescue nil
93
+ end
94
+ if !key && 'allowed_delay' == dow
95
+ @allowed_delay = hours.to_i
96
+ elsif key
97
+ hours = hours.split(',').map(&:strip).reject(&:empty?)
98
+ hours = hours.map { |hour| self.class.read_hour(hour) }.compact
99
+ acc[key] = hours if hours
100
+ end
101
+ acc
102
+ end
103
+
104
+ end
105
+
106
+ def self.read_hour(hour)
107
+ return unless hour =~ TIME_REGEX
108
+ h, m = if $1 && $2
109
+ h, m = $1.split(':').map(&:to_i)
110
+ h = 0 if 12 == h
111
+ h += 12 if 'P' == $2.upcase[0, 1]
112
+ [h, m]
113
+ else
114
+ $3.split(':').map(&:to_i)
115
+ end
116
+ m ||= 0
117
+ "%02d:%02d" % [h, m]
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,48 @@
1
+ #! /usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ # Tweep - Automatic Twitter Peeping
5
+ # Lets me rotate through tweets in a scheduled manner,
6
+ # with multiple accounts, and auto-retweet such tweets on other accounts yet.
7
+ #
8
+ # (c) 2011 Christophe Porteneuve
9
+
10
+ class Hash
11
+ # :nodoc:
12
+ # Inspired by ActiveSupport
13
+ def slice(*keys)
14
+ inject({}) do |acc, (k, v)|
15
+ acc[k] = v if keys.include?(k)
16
+ acc
17
+ end
18
+ end
19
+ end
20
+
21
+ class Object
22
+ alias_method :try, :__send__
23
+ end
24
+
25
+ class NilClass
26
+ # :nodoc:
27
+ # Inspired by ActiveSupport
28
+ def blank?; true; end
29
+
30
+ def try(*args); nil; end
31
+ end
32
+
33
+ class String
34
+ # :nodoc:
35
+ # Inspired by ActiveSupport
36
+ def blank?
37
+ strip.empty?
38
+ end
39
+ end
40
+
41
+ class Symbol
42
+ # :nodoc:
43
+ # For Ruby 1.8 compat, inspired by ActiveSupport
44
+ def to_proc
45
+ lambda { |o| o.send(self) }
46
+ end
47
+ end
48
+
@@ -0,0 +1,42 @@
1
+ #! /usr/bin/env ruby
2
+ # encoding: utf-8
3
+ #
4
+ # (c) 2011 Christophe Porteneuve
5
+
6
+ module Tweep
7
+ class Index
8
+ FILE_NAME = 'tweeping.idx'
9
+
10
+ def initialize
11
+ @states = {}
12
+ @states = YAML::load(File.read(FILE_NAME)) if File.exists?(FILE_NAME)
13
+ end
14
+
15
+ def next_retweet_in!(nick, retweeter, wait)
16
+ ((@states[nick] ||= {})[:waits] ||= {})[retweeter] = wait
17
+ end
18
+
19
+ def next_tweet_index(nick)
20
+ (@states[nick] ||= {})[:next].to_i
21
+ end
22
+
23
+ def retweet_timely?(nick, retweeter)
24
+ ((@states[nick] ||= {})[:waits] ||= {})[retweeter].to_i.zero?
25
+ end
26
+
27
+ def retweet_will_wait!(nick, retweeter)
28
+ wait = ((@states[nick] ||= {})[:waits] ||= {})[retweeter].to_i
29
+ @states[nick][:waits][retweeter] = [wait - 1, 0].max
30
+ end
31
+
32
+ def save!
33
+ File.open(FILE_NAME, 'w') { |f| f.write(YAML::dump(@states)) }
34
+ rescue Exception => e
35
+ Tweep.error "Could not save index to #{FILE_NAME} (#{e.class.name}: #{e.message})"
36
+ end
37
+
38
+ def tweeted!(nick, idx)
39
+ (@states[nick] ||= {})[:next] = idx + 1
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,33 @@
1
+ #! /usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ # Tweep - Automatic Twitter Peeping
5
+ # Lets me rotate through tweets in a scheduled manner,
6
+ # with multiple accounts, and auto-retweet such tweets on other accounts yet.
7
+ #
8
+ # (c) 2011 Christophe Porteneuve
9
+
10
+ require 'logger'
11
+
12
+ module Tweep
13
+ %w(error warn info).each do |level|
14
+ module_eval <<-EOC
15
+ def self.#{level}(*args)
16
+ logger.#{level}(*args)
17
+ end
18
+ EOC
19
+ end
20
+
21
+ def self.logger
22
+ return @logger if @logger
23
+ @logger = ARGV.include?('--log') ?
24
+ Logger.new('tweep.log', 5, 1_024 ** 2) :
25
+ Logger.new(STDOUT)
26
+ @logger.formatter = proc { |sev, datetime, progname, msg|
27
+ "[Tweep #{datetime} #{sev.to_s.upcase}] #{msg}\n"
28
+ }
29
+ @logger
30
+ end
31
+
32
+ private_class_method :logger
33
+ end
metadata ADDED
@@ -0,0 +1,85 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tweep
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - Christophe Porteneuve
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-12-13 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: twitter
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 2.0.2
24
+ type: :development
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: twitter
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 2.0.2
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ description: Tweep lets you rotate through tweets in a scheduled manner, with multiple accounts, and auto-retweet such tweets on other accounts yet. For instance, think recent accounts for product launches versus their more established company accounts.
38
+ email: tdd@tddsworld.com
39
+ executables:
40
+ - tweep
41
+ extensions: []
42
+
43
+ extra_rdoc_files: []
44
+
45
+ files:
46
+ - lib/tweep/account.rb
47
+ - lib/tweep/config.rb
48
+ - lib/tweep/core_exts.rb
49
+ - lib/tweep/index.rb
50
+ - lib/tweep/logging.rb
51
+ - lib/tweep.rb
52
+ - MIT-LICENSE.txt
53
+ - CHANGELOG.markdown
54
+ - README.markdown
55
+ - accounts/your_account_1.yml
56
+ - bin/tweep
57
+ homepage: http://github.com/tdd/tweep
58
+ licenses:
59
+ - MIT
60
+ post_install_message:
61
+ rdoc_options: []
62
+
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "0"
77
+ requirements: []
78
+
79
+ rubyforge_project:
80
+ rubygems_version: 1.8.10
81
+ signing_key:
82
+ specification_version: 3
83
+ summary: Automatic Twitter Peeping
84
+ test_files: []
85
+