tinatra 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.mkd ADDED
@@ -0,0 +1,80 @@
1
+ # Tinatra - Ruby powered DSL, which a designed for making twitter bots.
2
+
3
+ Tinatra is a DSL for making twitter bots. It's like Sinatra. トゥィナトラ.
4
+
5
+ ## Feature
6
+
7
+ * Easy to make twitter bot
8
+ * Run in cron
9
+ * Many actions (always,mention,direct\_message,followed,timeline,...)
10
+ * Automatic follow return/remove return
11
+
12
+ ## Install
13
+
14
+ gem install tinatra
15
+
16
+ ## Usage
17
+
18
+ require 'tinatra'
19
+
20
+ timeline do |tweet|
21
+ p tweet #=> New tweet in timeline
22
+ end
23
+
24
+ mention do |m|
25
+ p m #=> New tweet in mention
26
+ end
27
+
28
+ direct_message do |dm|
29
+ p dm #=> New Direct message
30
+ end
31
+
32
+ followed do |user|
33
+ p user #=> New user who is followed
34
+ end
35
+
36
+ removed do |user|
37
+ p user #=> User removed
38
+ end
39
+
40
+ always do
41
+ # Always run
42
+ end
43
+
44
+ ### Setup
45
+
46
+ $ ruby a.rb --db=/path/to/db --init
47
+ ------------ AUTHORIZING ------------
48
+ Input your consumer key: CONSUMERKEY
49
+ Input your consumer secret: PSSSSST
50
+
51
+ Access This URL and press 'Allow' in account for tinatra => http://...
52
+ Input key shown by twitter: 0000000
53
+
54
+ Authorizing is done.
55
+ $ ruby a.rb --db=/path/to/db
56
+
57
+ ## License
58
+
59
+ The MIT Licence
60
+
61
+ (c) Shota Fukumori (sora\_h) 2010-
62
+
63
+ >Permission is hereby granted, free of charge, to any person obtaining a copy
64
+ >of this software and associated documentation files (the "Software"), to deal
65
+ >in the Software without restriction, including without limitation the rights
66
+ >to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
67
+ >copies of the Software, and to permit persons to whom the Software is
68
+ >furnished to do so, subject to the following conditions:
69
+ >
70
+ >The above copyright notice and this permission notice shall be included in
71
+ >all copies or substantial portions of the Software.
72
+ >
73
+ >THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
74
+ >IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
75
+ >FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
76
+ >AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
77
+ >LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
78
+ >OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
79
+ >THE SOFTWARE.
80
+
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require 'jeweler'
2
+ Jeweler::Tasks.new do |gemspec|
3
+ gemspec.name = "tinatra"
4
+ gemspec.summary = "DSL for twitter bot!"
5
+ gemspec.email = "sora134@gmail.com"
6
+ gemspec.homepage = "http://github.com/sorah/tinatra"
7
+ gemspec.description = "Ruby implemented DSL, designed for twitter bot."
8
+ gemspec.authors = ["Shota Fukumori (sora_h)"]
9
+
10
+ gemspec.add_dependency 'rubytter'
11
+ gemspec.add_dependency 'highline'
12
+ gemspec.add_dependency 'oauth'
13
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,18 @@
1
+ $:.unshift "#{File.dirname(__FILE__)}/../lib"
2
+ require "tinatra"
3
+
4
+ mention do |m|
5
+ puts "mention #{m[:user][:screen_name]}: #{m[:text]}"
6
+ end
7
+
8
+ timeline do |m|
9
+ puts "timeline #{m[:user][:screen_name]}: #{m[:text]}"
10
+ end
11
+
12
+ direct_message do |m|
13
+ puts "dm #{m[:user][:screen_name]}: #{m[:text]}"
14
+ end
15
+
16
+ always do
17
+ puts "always"
18
+ end
data/lib/tinatra.rb ADDED
@@ -0,0 +1,269 @@
1
+ require 'rubygems'
2
+ require 'oauth'
3
+ require 'rubytter'
4
+ require 'pstore'
5
+ require 'singleton'
6
+ require 'highline'
7
+
8
+ class Hash
9
+ def transaction
10
+ yield self
11
+ end
12
+ end
13
+
14
+ #oauth-patch.rb http://d.hatena.ne.jp/shibason/20090802/1249204953
15
+ if RUBY_VERSION >= '1.9.0'
16
+ module OAuth
17
+ module Helper
18
+ def escape(value)
19
+ begin
20
+ URI::escape(value.to_s, OAuth::RESERVED_CHARACTERS)
21
+ rescue ArgumentError
22
+ URI::escape(
23
+ value.to_s.force_encoding(Encoding::UTF_8),
24
+ OAuth::RESERVED_CHARACTERS
25
+ )
26
+ end
27
+ end
28
+ end
29
+ end
30
+
31
+ module HMAC
32
+ class Base
33
+ def set_key(key)
34
+ key = @algorithm.digest(key) if key.size > @block_size
35
+ key_xor_ipad = Array.new(@block_size, 0x36)
36
+ key_xor_opad = Array.new(@block_size, 0x5c)
37
+ key.bytes.each_with_index do |value, index|
38
+ key_xor_ipad[index] ^= value
39
+ key_xor_opad[index] ^= value
40
+ end
41
+ @key_xor_ipad = key_xor_ipad.pack('c*')
42
+ @key_xor_opad = key_xor_opad.pack('c*')
43
+ @md = @algorithm.new
44
+ @initialized = true
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+
51
+
52
+ class Tinatra
53
+ API_BASE = 'http://api.twitter.com/'
54
+ include Singleton
55
+
56
+ def initialize
57
+ @config = {:rubytter => OAuthRubytter}
58
+ @actions = {}
59
+ @db = nil
60
+ @t = nil
61
+ end
62
+
63
+ def parse_option
64
+ init = false
65
+ help = false
66
+ ARGV.each do |a|
67
+ case a
68
+ when "--init"
69
+ init = true
70
+ help = false
71
+ when /--db=(.+)/
72
+ set :db, $1
73
+ when "--help"
74
+ help = true
75
+ init = false
76
+ end
77
+ end
78
+
79
+ if init
80
+ authorize
81
+ exit
82
+ end
83
+ if help
84
+ puts <<-EOH
85
+ Usage: #{File.basename($0)} [--db=DATABASE] [--init|--help]
86
+
87
+ --db -- set a path to database file.
88
+ --init -- authorize an account
89
+ --help -- show this message
90
+ EOH
91
+ exit
92
+ end
93
+ end
94
+
95
+ def authorize
96
+ puts "------------ AUTHORIZING ------------"
97
+ init_db
98
+ @db.transaction do |d|
99
+ if d[:consumer]
100
+ puts "You're already setted consumer key/secret."
101
+ cons_again = HighLine.new.agree("Input consumer key/secret again? ")
102
+ else
103
+ cons_again = true
104
+ end
105
+
106
+ if cons_again
107
+ cons = []
108
+ cons << HighLine.new.ask("Input your consumer key: ")
109
+ cons << HighLine.new.ask("Input your consumer secret: ")
110
+ d[:consumer] = OAuth::Consumer.new(cons[0],cons[1], :site => API_BASE)
111
+ end
112
+
113
+ puts
114
+
115
+ request_token = d[:consumer].get_request_token
116
+ puts "Access This URL and press 'Allow' in account for tinatra => #{request_token.authorize_url}"
117
+ pin = HighLine.new.ask('Input key shown by twitter: ')
118
+ access_token = request_token.get_access_token(
119
+ :oauth_verifier => pin
120
+ )
121
+ d[:token] = access_token#[access_token.token.dup,access_token.secret.dup]
122
+
123
+ @t = @config[:rubytter].new(access_token)
124
+ d[:self] = eval(@t.verify_credentials.inspect)
125
+
126
+ puts
127
+ puts "Authorizing is done."
128
+ end
129
+ end
130
+
131
+ def reset
132
+ initialize
133
+ end
134
+
135
+ def set(a,b)
136
+ @config[a]=b
137
+ end
138
+
139
+ def add_action(event, block)
140
+ @actions[event] ||= []
141
+ @actions[event] << block
142
+ end
143
+
144
+ def call_action(event, *args)
145
+ @actions[event] ||= []
146
+ @actions[event].each do |a|
147
+ a.yield(*args)
148
+ end
149
+ end
150
+
151
+ def run
152
+ init_db
153
+ init_twit
154
+
155
+ call_action(:always)
156
+
157
+ [[:mention, :replies], [:timeline, :home_timeline],
158
+ [:direct_message, :direct_messages]].each do |act|
159
+ if @actions[act[0]]
160
+ r = @t.__send__(act[1])
161
+ @db.transaction do |d|
162
+ (r - d[act[0]]).each do |new|
163
+ call_action(act[0],new)
164
+ end
165
+ d[act[0]] = eval(r.inspect)
166
+ end
167
+ end
168
+ end
169
+
170
+ @db.transaction do |d|
171
+ if @actions[:followed]||@actions[:removed]
172
+ f = @t.followers_ids(d[:self][:id])
173
+ [[:followed,(f-d[:follower])],
174
+ [:removed,(d[:follower]-f)]].each do |x|
175
+ if @actions[x[0]]
176
+ x[1].each do |n|
177
+ call_action(x[0],@t.user(n))
178
+ end
179
+ end
180
+ end
181
+ d[:follower] = eval(f.inspect)
182
+ end
183
+ end
184
+ end
185
+
186
+ def api
187
+ init_twit unless @t
188
+ @t
189
+ end
190
+
191
+ [:mention,:timeline,:direct_message,:always,:followed,:removed].each do |act|
192
+ eval "def #{act}(&block); add_action(:#{act},block); end"
193
+ end
194
+
195
+ def self.method_missing(name, *args)
196
+ Tinatra.instance.__send__(name, *args)
197
+ end
198
+
199
+ attr_reader :config
200
+
201
+ module Helpers
202
+ end
203
+ include Helpers
204
+
205
+ private
206
+
207
+ def init_twit
208
+ return @t if @t
209
+ init_db
210
+ @db.transaction do |d|
211
+ if d[:consumer].nil? || d[:token].nil?
212
+ abort "Run #{File.basename($0)} --init first." unless @config[:spec]
213
+ end
214
+ access_token = nil
215
+ if @config[:spec]
216
+ d[:self] = @config[:rubytter].new.verify_credentials
217
+ end
218
+ @t = @config[:rubytter].new(d[:token])
219
+ end
220
+ end
221
+
222
+ def init_db
223
+ return @db if @db
224
+ if @config[:db] == :memory
225
+ @db = {}
226
+ else
227
+ unless @config[:db]
228
+ abort "You must set a path to db file using --db= or db method."
229
+ end
230
+ @db = PStore.new(@config[:db])
231
+ end
232
+ make_db
233
+ end
234
+
235
+ def make_db
236
+ @db.transaction do |d|
237
+ unless d[:initialized]
238
+ d[:initialized] = true
239
+ [:mention,:direct_message,
240
+ :timeline,:follower,:following].each{|k|d[k]=[]}
241
+ end
242
+ end
243
+ end
244
+
245
+
246
+ end
247
+
248
+ module Kernel
249
+ def set(*args)
250
+ Tinatra.instance.set(*args)
251
+ end
252
+ def db(path)
253
+ Tinatra.instance.set(:db,path)
254
+ end
255
+ [:mention,:timeline,:direct_message,:always,:followed,:removed].each do |act|
256
+ eval "def #{act}(&block); Tinatra.instance.#{act}(&block); end"
257
+ end
258
+
259
+ def api
260
+ Tinatra.instance.api
261
+ end
262
+ end
263
+
264
+ at_exit do
265
+ if $!.nil? && !Tinatra.config[:spec]
266
+ Tinatra.parse_option
267
+ Tinatra.run
268
+ end
269
+ end
@@ -0,0 +1,101 @@
1
+ class Dummytter
2
+ @@dummy = {:replies => [], :home_timeline => [], :direct_messages => [],
3
+ :followers_ids => [], :friends_ids => []}
4
+ def method_missing(name,*args)
5
+ @@dummy[name] ||= []
6
+ @@dummy[name].dup
7
+ end
8
+
9
+ def user(id)
10
+ {:id=>id}
11
+ end
12
+
13
+ def self.dummy
14
+ @@dummy
15
+ end
16
+ end
17
+
18
+ $tinatra_spec_tweet_id = 0
19
+
20
+ def dummy_user(name)
21
+ $tinatra_spec_tweet_id += 1
22
+ {:profile_background_tile=>true,
23
+ :favourites_count=>0, :description=>"hi",
24
+ :profile_text_color=>"FFFFFF", :url=>"http://example.com/sorah",
25
+ :geo_enabled=>false, :follow_request_sent=>false, :lang=>"ja",
26
+ :created_at=>"Sat Sep 01 15:00:00 +0000 2009", :profile_link_color=>"FFFFFF",
27
+ :location=>"Tochigi", :verified=>false, :time_zone=>"Tokyo",
28
+ :profile_sidebar_fill_color=>"FFFFFF",
29
+ :profile_image_url=>"http://example.com/a.png",
30
+ :following=>true, :listed_count=>0, :profile_use_background_image=>true,
31
+ :profile_sidebar_border_color=>"FFFFFF",
32
+ :followers_count=>1, :protected=>false,
33
+ :screen_name=>name, :statuses_count=>1, :name=>name,
34
+ :show_all_inline_media=>false,
35
+ :profile_background_image_url=>"http://example.com/b.jpg",
36
+ :friends_count=>1, :id=>$tinatra_spec_tweet_id, :contributors_enabled=>false, :notifications=>false,
37
+ :utc_offset=>32400, :profile_background_color=>"FFFFFF"}
38
+ end
39
+
40
+ def dummy_tweet(t)
41
+ $tinatra_spec_tweet_id += 1
42
+ {:contributors=>nil, :in_reply_to_screen_name=>nil, :retweeted=>false,
43
+ :truncated=>false, :created_at=>"Mon Sep 13 12:00:00 +0000 2010",
44
+ :source=>"web",
45
+ :retweet_count=>nil,:in_reply_to_user_id=>nil, :favorited=>false,
46
+ :in_reply_to_status_id=>nil,
47
+ :place=>nil, :coordinates=>nil,
48
+ :user=>{:profile_background_tile=>true,
49
+ :favourites_count=>0, :description=>"hi",
50
+ :profile_text_color=>"FFFFFF", :url=>"http://example.com/sorah",
51
+ :geo_enabled=>false, :follow_request_sent=>false, :lang=>"ja",
52
+ :created_at=>"Sat Sep 01 15:00:00 +0000 2009", :profile_link_color=>"FFFFFF",
53
+ :location=>"Tochigi", :verified=>false, :time_zone=>"Tokyo",
54
+ :profile_sidebar_fill_color=>"FFFFFF",
55
+ :profile_image_url=>"http://example.com/a.png",
56
+ :following=>true, :listed_count=>0, :profile_use_background_image=>true,
57
+ :profile_sidebar_border_color=>"FFFFFF",
58
+ :followers_count=>1, :protected=>false,
59
+ :screen_name=>"foo", :statuses_count=>1, :name=>"foobar",
60
+ :show_all_inline_media=>false,
61
+ :profile_background_image_url=>"http://example.com/b.jpg",
62
+ :friends_count=>1, :id=>1, :contributors_enabled=>false, :notifications=>false,
63
+ :utc_offset=>32400, :profile_background_color=>"FFFFFF"},
64
+ :geo=>nil, :id=>$tinatra_spec_tweet_id, :text=>t}
65
+ end
66
+
67
+ def dummy_reply(i,t)
68
+ $tinatra_spec_tweet_id += 1
69
+ {:contributors=>nil, :in_reply_to_screen_name=>"tinatra", :retweeted=>false,
70
+ :truncated=>false, :created_at=>"Mon Sep 13 12:00:00 +0000 2010",
71
+ :source=>"web",
72
+ :retweet_count=>nil,:in_reply_to_user_id=>2, :favorited=>false,
73
+ :in_reply_to_status_id=>i,
74
+ :place=>nil, :coordinates=>nil,
75
+ :user=>{:profile_background_tile=>true,
76
+ :favourites_count=>0, :description=>"hi",
77
+ :profile_text_color=>"FFFFFF", :url=>"http://example.com/sorah",
78
+ :geo_enabled=>false, :follow_request_sent=>false, :lang=>"ja",
79
+ :created_at=>"Sat Sep 01 15:00:00 +0000 2009", :profile_link_color=>"FFFFFF",
80
+ :location=>"Tochigi", :verified=>false, :time_zone=>"Tokyo",
81
+ :profile_sidebar_fill_color=>"FFFFFF",
82
+ :profile_image_url=>"http://example.com/a.png",
83
+ :following=>true, :listed_count=>0, :profile_use_background_image=>true,
84
+ :profile_sidebar_border_color=>"FFFFFF",
85
+ :followers_count=>1, :protected=>false,
86
+ :screen_name=>"foo", :statuses_count=>1, :name=>"foobar",
87
+ :show_all_inline_media=>false,
88
+ :profile_background_image_url=>"http://example.com/b.jpg",
89
+ :friends_count=>1, :id=>1, :contributors_enabled=>false, :notifications=>false,
90
+ :utc_offset=>32400, :profile_background_color=>"FFFFFF"},
91
+ :geo=>nil, :id=>$tinatra_spec_tweet_id, :text=>t}
92
+
93
+ end
94
+
95
+ def dummy_direct(text)
96
+ {:recipient_screen_name=>"tinatra", :recipient=>{},
97
+ :created_at=>"Mon Sep 13 07:11:39 +0000 2010", :recipient_id=>2, :sender=>{},
98
+ :sender_id=>1, :id=>$tinatra_spec_tweet_id, :sender_screen_name=>"foo", :text=>text}
99
+ end
100
+
101
+
@@ -0,0 +1,131 @@
1
+ $:.unshift "#{File.dirname(__FILE__)}/../lib"
2
+ $:.unshift "#{File.dirname(__FILE__)}"
3
+ require "tinatra"
4
+ require "helper_dummytter"
5
+
6
+ #Dummytter.dummy[:followers_ids] = 100.times.map{|i|i}
7
+
8
+ describe "Tinatra" do
9
+ before do
10
+ Dummytter.dummy[:verify_credentials] = {:user => {:id => 2, :screen_name => "tinatra"}}
11
+ Tinatra.set :spec, true
12
+ Tinatra.set :db, :memory
13
+ Tinatra.set :rubytter, Dummytter
14
+ end
15
+ it "sets config by Kernel#set" do
16
+ Kernel.set :foo, :bar
17
+ Tinatra.config[:foo].should == :bar
18
+ end
19
+
20
+ it "adds and calls an action" do
21
+ Tinatra.reset
22
+ a = nil
23
+ l = lambda{ a = :twitra}
24
+ Tinatra.add_action(:foo, l)
25
+ Tinatra.call_action(:foo)
26
+ a.should == :twitra
27
+ end
28
+
29
+ it "adds and calls an action with args" do
30
+ Tinatra.reset
31
+ a = nil
32
+ l = lambda{|*x| a = x}
33
+ Tinatra.add_action(:foo, l)
34
+ Tinatra.call_action(:foo, :bar)
35
+ a.should == [:bar]
36
+ Tinatra.call_action(:foo, :bar, :hoge)
37
+ a.should == [:bar, :hoge]
38
+ end
39
+
40
+ describe "action" do
41
+ it "timeline calls when detect new tweet in timeline" do
42
+ r = nil
43
+ tweet = dummy_tweet("hi")
44
+ a = lambda{|t|r = t[:id]}
45
+ Tinatra.add_action(:timeline, a)
46
+ Tinatra.run
47
+ Dummytter.dummy[:home_timeline] << tweet
48
+ Tinatra.run
49
+ r.should == tweet[:id]
50
+ end
51
+
52
+ it "mention calls when detect new tweet in mention" do
53
+ r = nil
54
+ target = dummy_tweet("hi")
55
+ mention = dummy_reply(target[:id],"hi!!")
56
+ Dummytter.dummy[:home_timeline] << target
57
+ a = lambda{|t|r=t[:id]}
58
+ Tinatra.add_action(:mention, a)
59
+ Tinatra.run
60
+ Dummytter.dummy[:replies] << mention
61
+ Tinatra.run
62
+ r.should == mention[:id]
63
+ end
64
+
65
+ it "direct_message calls when received new direct message" do
66
+ dm = dummy_direct("hello")
67
+ r = nil
68
+ a = lambda{|d|r = d[:id]}
69
+ Tinatra.add_action(:direct_message, a)
70
+ Tinatra.run
71
+ Dummytter.dummy[:direct_messages] << dm
72
+ Tinatra.run
73
+ r.should == dm[:id]
74
+ end
75
+
76
+ it "always calls always" do
77
+ r = false
78
+ a = lambda{r = true}
79
+ Tinatra.add_action(:always, a)
80
+ Tinatra.run
81
+ r.should be_true
82
+ end
83
+
84
+ it "followed calls when followed by user" do
85
+ r = nil
86
+ a = lambda{|u|r = u[:id]}
87
+ Tinatra.run
88
+ Tinatra.add_action(:followed,a)
89
+ Dummytter.dummy[:followers_ids] << 10000
90
+ Tinatra.run
91
+ r.should == 10000
92
+ end
93
+
94
+ it "removed calls when removed by user" do
95
+ r = nil
96
+ a = lambda{|u|r = u[:id]}
97
+ Tinatra.run
98
+ Tinatra.add_action(:removed,a)
99
+ Dummytter.dummy[:followers_ids].delete 10000
100
+ Tinatra.run
101
+ r.should == 10000
102
+ end
103
+
104
+ it "looks rubytter by api method" do
105
+ r = nil
106
+ a = lambda{r = api.class}
107
+ Tinatra.add_action(:always, a)
108
+ Tinatra.run
109
+ r.should == Dummytter
110
+ end
111
+
112
+ it "add by method" do
113
+ r = false
114
+ always do
115
+ r = true
116
+ end
117
+ Tinatra.run
118
+ r.should be_true
119
+ end
120
+ end
121
+
122
+ describe "config" do
123
+ it "autofollow returns follow automatically" do
124
+ pending
125
+ end
126
+
127
+ it "autoremove returns follow automatically" do
128
+ pending
129
+ end
130
+ end
131
+ end
data/tinatra.gemspec ADDED
@@ -0,0 +1,58 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{tinatra}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Shota Fukumori (sora_h)"]
12
+ s.date = %q{2010-09-14}
13
+ s.description = %q{Ruby implemented DSL, designed for twitter bot.}
14
+ s.email = %q{sora134@gmail.com}
15
+ s.extra_rdoc_files = [
16
+ "README.mkd"
17
+ ]
18
+ s.files = [
19
+ "README.mkd",
20
+ "Rakefile",
21
+ "VERSION",
22
+ "examples/simple.rb",
23
+ "lib/tinatra.rb",
24
+ "spec/helper_dummytter.rb",
25
+ "spec/spec_tinatra.rb",
26
+ "tinatra.gemspec"
27
+ ]
28
+ s.homepage = %q{http://github.com/sorah/tinatra}
29
+ s.rdoc_options = ["--charset=UTF-8"]
30
+ s.require_paths = ["lib"]
31
+ s.rubygems_version = %q{1.3.7}
32
+ s.summary = %q{DSL for twitter bot!}
33
+ s.test_files = [
34
+ "spec/helper_dummytter.rb",
35
+ "spec/spec_tinatra.rb",
36
+ "examples/simple.rb"
37
+ ]
38
+
39
+ if s.respond_to? :specification_version then
40
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
41
+ s.specification_version = 3
42
+
43
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
44
+ s.add_runtime_dependency(%q<rubytter>, [">= 0"])
45
+ s.add_runtime_dependency(%q<highline>, [">= 0"])
46
+ s.add_runtime_dependency(%q<oauth>, [">= 0"])
47
+ else
48
+ s.add_dependency(%q<rubytter>, [">= 0"])
49
+ s.add_dependency(%q<highline>, [">= 0"])
50
+ s.add_dependency(%q<oauth>, [">= 0"])
51
+ end
52
+ else
53
+ s.add_dependency(%q<rubytter>, [">= 0"])
54
+ s.add_dependency(%q<highline>, [">= 0"])
55
+ s.add_dependency(%q<oauth>, [">= 0"])
56
+ end
57
+ end
58
+
metadata ADDED
@@ -0,0 +1,111 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tinatra
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 0
9
+ version: 0.1.0
10
+ platform: ruby
11
+ authors:
12
+ - Shota Fukumori (sora_h)
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-09-14 00:00:00 +09:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rubytter
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
31
+ type: :runtime
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
34
+ name: highline
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
37
+ none: false
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
44
+ type: :runtime
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
47
+ name: oauth
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
57
+ type: :runtime
58
+ version_requirements: *id003
59
+ description: Ruby implemented DSL, designed for twitter bot.
60
+ email: sora134@gmail.com
61
+ executables: []
62
+
63
+ extensions: []
64
+
65
+ extra_rdoc_files:
66
+ - README.mkd
67
+ files:
68
+ - README.mkd
69
+ - Rakefile
70
+ - VERSION
71
+ - examples/simple.rb
72
+ - lib/tinatra.rb
73
+ - spec/helper_dummytter.rb
74
+ - spec/spec_tinatra.rb
75
+ - tinatra.gemspec
76
+ has_rdoc: true
77
+ homepage: http://github.com/sorah/tinatra
78
+ licenses: []
79
+
80
+ post_install_message:
81
+ rdoc_options:
82
+ - --charset=UTF-8
83
+ require_paths:
84
+ - lib
85
+ required_ruby_version: !ruby/object:Gem::Requirement
86
+ none: false
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ segments:
99
+ - 0
100
+ version: "0"
101
+ requirements: []
102
+
103
+ rubyforge_project:
104
+ rubygems_version: 1.3.7
105
+ signing_key:
106
+ specification_version: 3
107
+ summary: DSL for twitter bot!
108
+ test_files:
109
+ - spec/helper_dummytter.rb
110
+ - spec/spec_tinatra.rb
111
+ - examples/simple.rb