shiki 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .DS_Store
5
+ .config
6
+ .yardoc
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/*
17
+ tmp
data/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ 0.0.1
2
+ ------------
3
+
4
+ First release!
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in shiki.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Oame
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,52 @@
1
+ 式(Shiki) beta
2
+ =============
3
+
4
+ Shiki is The "Unidentified" Bot Framework for Twitter. written in Ruby.
5
+
6
+ Features / Problems
7
+ -------------
8
+
9
+ * Easy to write.
10
+
11
+ Requirement
12
+ -------------
13
+
14
+ * pupil, json and oauth gem
15
+ * Ruby 1.9.x
16
+
17
+ Installation
18
+ -------------
19
+
20
+ gem install shiki
21
+
22
+ Examples
23
+ -------------
24
+ require "shiki"
25
+
26
+ OAUTH_KEY = {
27
+ :consumer_key => "something", # Required
28
+ :consumer_secret => "something" # Required
29
+ :access_token => "something", # Required
30
+ :access_token_secret => "something" # Required
31
+ }
32
+
33
+ class UsefullBot < Shiki::Base
34
+ set :oauth_key, OAUTH_KEY
35
+ use :memory, :database => "databases/memory.db"
36
+
37
+ event :mention do |status|
38
+ status.user.reply "Guten morgen!"
39
+ end
40
+ end
41
+
42
+ Credits
43
+ -------------
44
+
45
+ Developer: [Oame](http://twitter.com/o_ame)
46
+
47
+ License
48
+ -------------
49
+
50
+ Copyright (c) 2011 Oame. See LICENSE.txt for
51
+ further details.
52
+
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ desc "Run RSpec test"
5
+ task :test do
6
+ `rspec -c spec/valid_test_rspec.rb`
7
+ end
8
+
9
+ desc "Pulling repository from master"
10
+ task :update do
11
+ `git pull origin master`
12
+ end
data/lib/shiki.rb ADDED
@@ -0,0 +1,5 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ $LOAD_PATH << File.dirname(File.expand_path(__FILE__))
4
+ require "shiki/version"
5
+ require "shiki/base"
data/lib/shiki/base.rb ADDED
@@ -0,0 +1,223 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ require "net/https"
4
+ require "time"
5
+ require "json"
6
+ require "oauth"
7
+ require "pupil"
8
+ require "pupil/stream"
9
+ require "shiki/fuda"
10
+ #require "shiki/personality"
11
+
12
+ module Shiki
13
+ class Base
14
+ attr_accessor :memory
15
+
16
+ TWITTER_URL = "http://twitter.com"
17
+ TWITTER_USERSTREAM_API = "https://userstream.twitter.com/2/user.json"
18
+
19
+ SCHEMES = [
20
+ [:status, :mention, :follow, :favorite, :retweet],
21
+ [:search]
22
+ ]
23
+
24
+ def initialize
25
+ super()
26
+ @key = self.oauth_key
27
+ @consumer = OAuth::Consumer.new(@key[:consumer_key], @key[:consumer_secret], :site => TWITTER_URL)
28
+ @access_token = OAuth::AccessToken.new(@consumer, @key[:access_token], @key[:access_token_secret])
29
+ register(:twitter => Pupil.new(@key))
30
+
31
+ #register(:memory => Shiki::Memory.new(self.memory_database))
32
+ end
33
+
34
+ def register(option)
35
+ self.class.register(option)
36
+ end
37
+
38
+ def call(action, num, option=nil)
39
+ self.class.call(action, num, option)
40
+ end
41
+
42
+ def disharmony?(keys)
43
+ i1 = keys.map{|k| SCHEMES[0].include?(k)}
44
+ i2 = keys.map{|k| SCHEMES[1].include?(k)}
45
+ return ((i1&i2).size > 0)? true : false
46
+ end
47
+
48
+ def guess_scheme(keys)
49
+ if keys.map{|k| SCHEMES[0].index(k)}
50
+ return :userstream
51
+ else
52
+ return :search
53
+ end
54
+ end
55
+
56
+ def run
57
+ keys = self.class.blocks.keys
58
+ raise ArgumentError, "Disharnomy event blocks are detected." if disharmony?(keys)
59
+ raise NoMethodError, "self.oauth_key not defined" unless self.respond_to? :oauth_key
60
+
61
+ scheme = guess_scheme(keys)
62
+ ps = Pupil::Stream.new self.oauth_key
63
+ begin
64
+ ps.start scheme do |status|
65
+ #puts "Event: #{status.event}"
66
+ case status.event
67
+ when :status
68
+ if status.text.match /^@/
69
+ # Mention event
70
+ next unless self.class.blocks[:mention]
71
+ proc_status_event(:mention, status)
72
+ else
73
+ # Status event
74
+ next unless self.class.blocks[:status]
75
+ proc_status_event(:status, status)
76
+ end
77
+ when :retweet
78
+ # Retweeted event
79
+ next unless self.class.blocks[:retweet]
80
+ proc_status_event(:retweet, status)
81
+ when :follow
82
+ # Foolow event
83
+ next unless self.class.blocks[:follow]
84
+ proc_follow(status)
85
+ end
86
+ end
87
+ rescue Interrupt
88
+ puts "> Stopping ..."
89
+ exit()
90
+ end
91
+ end
92
+
93
+ def proc_follow(status)
94
+ blocks = self.class.blocks[:follow]
95
+ num = 0
96
+ blocks.each do |block|
97
+ option = block[:option]
98
+ call(:follow, num, status)
99
+ num += 1
100
+ end
101
+ end
102
+
103
+ def proc_status_event(event, status)
104
+ blocks = self.class.blocks[event]
105
+ num = 0
106
+ blocks.each do |block|
107
+ option = block[:option]
108
+ if option
109
+ response = []
110
+
111
+ if option[:include]
112
+ if Regexp.new(option[:include]) =~ status.text
113
+ response << true
114
+ else
115
+ response << false
116
+ end
117
+ end
118
+
119
+ if option[:from]
120
+ if option[:from].to_s == status.user.screen_name
121
+ response << true
122
+ else
123
+ response << false
124
+ end
125
+ end
126
+
127
+ if response.index(false) == nil
128
+ call(event, num, status)
129
+ next
130
+ else
131
+ next
132
+ end
133
+ end
134
+
135
+ call(event, num, status)
136
+ num += 1
137
+ end
138
+ end
139
+
140
+ class << self
141
+ @@blocks = {}
142
+ @@conditions = {}
143
+ @@env = {}
144
+
145
+ # Accessor methods
146
+
147
+ def blocks; @@blocks; end
148
+ def env(param); @@env[param]; end
149
+
150
+ def register(opt)
151
+ option = [*opt][0]
152
+ @@conditions[option[0]] = option[1]
153
+ end
154
+
155
+ def call(action, num, option)
156
+ @@blocks[action][num][:block].call option
157
+ end
158
+
159
+ def set(option, value=nil)
160
+ #class_eval "def self.#{option}() #{value.inspect} ; end"
161
+ define_method option, proc{ value }
162
+ end
163
+
164
+ def use(name, option=nil)
165
+ require(File.join(File.dirname(File.expand_path($0)), "fuda/#{name}"))
166
+ fuda = eval("#{name.capitalize}")
167
+ @@env[:fuda] ||= {}
168
+ if fuda.prepare[:make_instance]
169
+ @@env[:fuda].update(name.to_sym => {:block => fuda.new(option), :option => option, :instance => true})
170
+ else
171
+ @@env[:fuda].update(name.to_sym => {:block => fuda, :option => option, :instance => false})
172
+ eval("#{name.capitalize}.new(#{option})")
173
+ end
174
+ end
175
+
176
+ def enable(fuda, option)
177
+ # Not implement
178
+ # e.g. auto_follow
179
+ end
180
+
181
+ def event(action, option=nil, &block)
182
+ @@blocks[action] ||= []
183
+ @@blocks[action] << {:block => block, :option => option}
184
+ end
185
+
186
+ def method_missing(action, *option)
187
+ @@env[:fuda].each do |name, option|
188
+ return option[:block] if action == name && option[:instance]
189
+ end
190
+ raise NoMethodError
191
+ end
192
+
193
+ # Bot methods
194
+
195
+ def say(sentence)
196
+ @@conditions[:twitter].update(sentence)
197
+ end
198
+
199
+ alias_method :tweet, :say
200
+
201
+ def reply(opts, status=nil)
202
+ puts "get reply"
203
+ raise ArgumentError, "target parameter not given" unless opts.values[0]
204
+ sentence, target = opts.to_a.first
205
+ name = nil
206
+ case target.class.to_s
207
+ when "Pupil::User"
208
+ name = target.screen_name
209
+ when "String"
210
+ name = target
211
+ when "Symbol"
212
+ name = target.to_s
213
+ end
214
+ if status
215
+ @@conditions[:twitter].update("@#{name} #{sentence}", status)
216
+ else
217
+ @@conditions[:twitter].update("@#{name} #{sentence}")
218
+ end
219
+ end
220
+
221
+ end
222
+ end
223
+ end
data/lib/shiki/fuda.rb ADDED
@@ -0,0 +1,17 @@
1
+ module Shiki
2
+ class Fuda
3
+ def initialize()
4
+ super()
5
+ end
6
+
7
+ def self.prepare
8
+ {
9
+ :make_instance => true
10
+ }
11
+ end
12
+
13
+ def self.depends
14
+ []
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,24 @@
1
+ require "sequel"
2
+
3
+ module Shiki
4
+ class Personality
5
+ def initialize pattern_db
6
+ @db = Sequel.sqlite pattern_db
7
+ @tweets = @db[:tweets]
8
+ @replies = @db[:replies]
9
+ @locations = @db[:locations]
10
+ end
11
+
12
+ def tweets time_zone, week
13
+
14
+ end
15
+
16
+ def replies fear, interest
17
+
18
+ end
19
+
20
+ def random_location
21
+ return @locations.to_a
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,3 @@
1
+ module Shiki
2
+ VERSION = "0.0.1"
3
+ end
data/shiki.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/shiki/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Oame"]
6
+ gem.email = ["oame@oameya.com"]
7
+ gem.description = %q{The "Unidentified" Bot Framework}
8
+ gem.summary = %q{The "Unidentified" Bot Framework for Twitter.}
9
+ gem.homepage = "https://github.com/oame/shiki"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "shiki"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Shiki::VERSION
17
+ gem.add_dependency "json"
18
+ gem.add_dependency "oauth"
19
+ gem.add_dependency "pupil"
20
+ gem.add_development_dependency "rspec"
21
+ end
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env ruby
2
+ #! -*- coding: utf-8 -*-
3
+
4
+ require "rubygems"
5
+ require "rspec"
6
+ require "yaml"
7
+
8
+ TWEETS_FILE = "tweets.yml"
9
+ REPLY_PATTERNS_FILE = "reply_patterns.yml"
10
+ LOCATIONS_FILE = "locations.yml"
11
+
12
+ describe "YAML Configurations" do
13
+ before do
14
+ @tweets = YAML.load_file TWEETS_FILE
15
+ @replies = YAML.load_file REPLY_PATTERNS_FILE
16
+ @locations = YAML.load_file LOCATIONS_FILE
17
+ end
18
+
19
+ it "TweetsはHash型であること" do
20
+ @tweets.class.should == Hash
21
+ end
22
+
23
+ it "RepliesはHash型であること" do
24
+ @replies.class.should == Hash
25
+ end
26
+
27
+ it "LocationsはArray型であること" do
28
+ @locations.class.should == Array
29
+ end
30
+ end
metadata ADDED
@@ -0,0 +1,104 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: shiki
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Oame
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-05-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: json
16
+ requirement: &70329096636120 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70329096636120
25
+ - !ruby/object:Gem::Dependency
26
+ name: oauth
27
+ requirement: &70329096635340 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *70329096635340
36
+ - !ruby/object:Gem::Dependency
37
+ name: pupil
38
+ requirement: &70329096634160 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :runtime
45
+ prerelease: false
46
+ version_requirements: *70329096634160
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &70329096633540 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70329096633540
58
+ description: The "Unidentified" Bot Framework
59
+ email:
60
+ - oame@oameya.com
61
+ executables: []
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - .gitignore
66
+ - CHANGELOG.md
67
+ - Gemfile
68
+ - LICENSE
69
+ - README.md
70
+ - Rakefile
71
+ - lib/shiki.rb
72
+ - lib/shiki/base.rb
73
+ - lib/shiki/fuda.rb
74
+ - lib/shiki/personality.rb
75
+ - lib/shiki/version.rb
76
+ - shiki.gemspec
77
+ - spec/valid_test_spec.rb
78
+ homepage: https://github.com/oame/shiki
79
+ licenses: []
80
+ post_install_message:
81
+ rdoc_options: []
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ required_rubygems_version: !ruby/object:Gem::Requirement
91
+ none: false
92
+ requirements:
93
+ - - ! '>='
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ requirements: []
97
+ rubyforge_project:
98
+ rubygems_version: 1.8.15
99
+ signing_key:
100
+ specification_version: 3
101
+ summary: The "Unidentified" Bot Framework for Twitter.
102
+ test_files:
103
+ - spec/valid_test_spec.rb
104
+ has_rdoc: