tweep 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+