protolink 0.2.7 → 0.2.8
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -0
- data/Gemfile.lock +12 -0
- data/README.markdown +15 -4
- data/example/chatbot.rb +24 -0
- data/example/create_and_subscribe.rb +5 -1
- data/example/linkbot/base_plugins.rb +71 -0
- data/example/linkbot/plugins/awwwyeah.rb +11 -0
- data/example/linkbot/plugins/blowhard.rb +40 -0
- data/example/linkbot/plugins/comic.rb +40 -0
- data/example/linkbot/plugins/dumb.rb +11 -0
- data/example/linkbot/plugins/dupe.rb.inactive +64 -0
- data/example/linkbot/plugins/face.rb +11 -0
- data/example/linkbot/plugins/fuuu.rb +12 -0
- data/example/linkbot/plugins/help.rb +26 -0
- data/example/linkbot/plugins/image.rb +30 -0
- data/example/linkbot/plugins/imgur.rb +31 -0
- data/example/linkbot/plugins/jason.rb +73 -0
- data/example/linkbot/plugins/karma.rb.inactive +75 -0
- data/example/linkbot/plugins/last.rb +40 -0
- data/example/linkbot/plugins/links.rb.inactive +41 -0
- data/example/linkbot/plugins/log.rb +17 -0
- data/example/linkbot/plugins/okay.rb +11 -0
- data/example/linkbot/plugins/onion.rb +19 -0
- data/example/linkbot/plugins/popcorn.rb +32 -0
- data/example/linkbot/plugins/qwantz.rb +29 -0
- data/example/linkbot/plugins/search.rb +32 -0
- data/example/linkbot/plugins/shutup.rb +11 -0
- data/example/linkbot/plugins/slap.rb +15 -0
- data/example/linkbot/plugins/snap.rb +18 -0
- data/example/linkbot/plugins/stab.rb +12 -0
- data/example/linkbot/plugins/store.rb +71 -0
- data/example/linkbot/plugins/store_help.rb +22 -0
- data/example/linkbot/plugins/swanson.rb +41 -0
- data/example/linkbot/plugins/titles.rb +34 -0
- data/example/linkbot/plugins/translate.rb +21 -0
- data/example/linkbot/plugins/tsa.rb +22 -0
- data/example/linkbot/plugins/twss.rb +20 -0
- data/example/linkbot/plugins/urban.rb +27 -0
- data/example/linkbot/util.rb +28 -0
- data/lib/protolink.rb +4 -0
- data/lib/protolink/channel.rb +4 -0
- data/lib/protolink/flash_connection.rb +47 -0
- data/lib/protolink/proto_socket.rb +33 -0
- data/lib/protolink/protonet.rb +18 -3
- data/lib/protolink/version.rb +1 -1
- data/test/all_tests.rb +2 -2
- metadata +41 -4
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,17 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
+
addressable (2.2.6)
|
4
5
|
crack (0.1.8)
|
6
|
+
em-http-request (1.0.0)
|
7
|
+
addressable (>= 2.2.3)
|
8
|
+
em-socksify
|
9
|
+
eventmachine (>= 1.0.0.beta.3)
|
10
|
+
http_parser.rb (>= 0.5.2)
|
11
|
+
em-socksify (0.1.0)
|
12
|
+
eventmachine
|
13
|
+
eventmachine (1.0.0.beta.4)
|
14
|
+
http_parser.rb (0.5.3)
|
5
15
|
httparty (0.7.8)
|
6
16
|
crack (= 0.1.8)
|
7
17
|
rake (0.9.2)
|
@@ -11,6 +21,8 @@ PLATFORMS
|
|
11
21
|
ruby
|
12
22
|
|
13
23
|
DEPENDENCIES
|
24
|
+
em-http-request
|
25
|
+
eventmachine (= 1.0.0.beta.4)
|
14
26
|
httparty
|
15
27
|
rake
|
16
28
|
rcov
|
data/README.markdown
CHANGED
@@ -4,14 +4,13 @@ ProtoLink is a library for interfacing with ProtoNet, the next-gen internet infr
|
|
4
4
|
|
5
5
|
Version: 0.2.1
|
6
6
|
|
7
|
-
|
7
|
+
Tests are in test/all_test.rb.
|
8
8
|
|
9
9
|
|
10
10
|
## Dependencies
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
See Gemfile
|
13
|
+
|
15
14
|
## Usage
|
16
15
|
|
17
16
|
# CHANNELS
|
@@ -142,6 +141,18 @@ Sorry, there are no tests at all yet...
|
|
142
141
|
|
143
142
|
gem install protolink
|
144
143
|
|
144
|
+
## IRB
|
145
|
+
|
146
|
+
$LOAD_PATH.unshift "#{`pwd`.strip}/lib" # project directory
|
147
|
+
require 'rubygems'
|
148
|
+
require 'protolink'
|
149
|
+
require 'ruby-debug'
|
150
|
+
Debugger.start
|
151
|
+
# change this if you need to connect to another server
|
152
|
+
PTN_SERVER = "http://localhost:3000"
|
153
|
+
PTN_USER = "admin"
|
154
|
+
PTN_PASS = "admin"
|
155
|
+
protonet = Protolink::Protonet.open(PTN_SERVER, PTN_USER, PTN_PASS)
|
145
156
|
|
146
157
|
## How to contribute
|
147
158
|
|
data/example/chatbot.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'protolink'
|
5
|
+
require 'linkbot/base_plugins'
|
6
|
+
|
7
|
+
# require 'ruby-debug'
|
8
|
+
# Debugger.start
|
9
|
+
|
10
|
+
# from https://github.com/markolson/linkbot
|
11
|
+
Linkbot::Plugin.collect
|
12
|
+
|
13
|
+
# change this if you need to connect to another server
|
14
|
+
PTN_SERVER = "http://localhost:3000"
|
15
|
+
PTN_USER = "admin"
|
16
|
+
PTN_PASS = "admin"
|
17
|
+
protonet = Protolink::Protonet.open(PTN_SERVER, PTN_USER, PTN_PASS)
|
18
|
+
protonet.socket do |json|
|
19
|
+
response = Linkbot::Plugin.handle_message(Message.new(json["message"], json["user_id"], json["author"], :message)) if json["trigger"] == "meep.receive"
|
20
|
+
unless response.blank?
|
21
|
+
c = protonet.find_channel(json["channel_id"])
|
22
|
+
c.speak(response.first)
|
23
|
+
end
|
24
|
+
end
|
@@ -1,7 +1,11 @@
|
|
1
|
+
$LOAD_PATH.unshift "#{File.dirname(__FILE__)}/../lib"
|
2
|
+
|
1
3
|
require 'rubygems'
|
2
4
|
require 'protolink'
|
3
5
|
|
4
|
-
|
6
|
+
# FOR MORE CURRENT EXAMPLES PLEASE CHECK test/all_tests.rb - THANKS!
|
7
|
+
|
8
|
+
protonet = Protolink::Protonet.open('http://localhost:3000', 'admin', 'admin')
|
5
9
|
|
6
10
|
user = protonet.find_or_create_user_by_login("johndoe", :password => "password", :name => "John Doe", :email => "john@doe.com")
|
7
11
|
auth_token = user.auth_token
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'pp'
|
3
|
+
require 'hpricot'
|
4
|
+
|
5
|
+
class MessageType
|
6
|
+
MESSAGE = :message
|
7
|
+
DIRECTMESSAGE = :"direct-message"
|
8
|
+
STARRED = :starred
|
9
|
+
UNSTARRED = :unstarred
|
10
|
+
end
|
11
|
+
|
12
|
+
#The interface message object between Linkbot::Plugin and the plugins.
|
13
|
+
#New axiom: the plugins know nothing about the service they're using!
|
14
|
+
Message = Struct.new(:body, :user_id, :user_name, :type)
|
15
|
+
|
16
|
+
class Linkbot
|
17
|
+
class Plugin
|
18
|
+
@@plugins = {}
|
19
|
+
@@message_log = []
|
20
|
+
|
21
|
+
def self.handle_message(message)
|
22
|
+
print "handle_message got called with #{message}"
|
23
|
+
|
24
|
+
@@message_log << message
|
25
|
+
|
26
|
+
final_message = []
|
27
|
+
|
28
|
+
Linkbot::Plugin.plugins.each {|k,v|
|
29
|
+
if v[:handlers][message.type] && v[:handlers][message.type][:handler]
|
30
|
+
|
31
|
+
if ((v[:handlers][message.type][:regex] && v[:handlers][message.type][:regex].match(message.body)) || v[:handlers][message.type][:regex].nil?)
|
32
|
+
|
33
|
+
matches = v[:handlers][message.type][:regex] ? v[:handlers][message.type][:regex].match(message.body).to_a.drop(1) : nil
|
34
|
+
p "#{k} processing message type #{message.type}"
|
35
|
+
begin
|
36
|
+
end_msg = v[:ptr].send(v[:handlers][message.type][:handler], message, matches)
|
37
|
+
rescue => e
|
38
|
+
end_msg = "the #{k} plugin threw an exception: #{e.inspect}"
|
39
|
+
puts e.inspect
|
40
|
+
puts e.backtrace.join("\n")
|
41
|
+
end
|
42
|
+
final_message << end_msg if !end_msg.empty?
|
43
|
+
end
|
44
|
+
end
|
45
|
+
}
|
46
|
+
print "returning msgs from plugins:"
|
47
|
+
pp final_message
|
48
|
+
final_message
|
49
|
+
end
|
50
|
+
|
51
|
+
def self.message_history
|
52
|
+
@@message_log
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.registered_methods
|
56
|
+
@registered_methods ||= {}
|
57
|
+
@registered_methods
|
58
|
+
end
|
59
|
+
|
60
|
+
def self.plugins; @@plugins; end;
|
61
|
+
|
62
|
+
def self.collect
|
63
|
+
Dir["linkbot/plugins/*.rb"].each {|file| load file }
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.register(name, s, handlers)
|
67
|
+
@@plugins[name] = {:ptr => s, :handlers => handlers}
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
class Blowhard < Linkbot::Plugin
|
2
|
+
def self.on_message(message, matches)
|
3
|
+
quotes = ['I just blue myself.',
|
4
|
+
"I'll be your wingman. Even if it means I have to take a chubby. I will suck it up.",
|
5
|
+
"Well, yes, but I'm afraid I prematurely shot my wad on what was supposed to be a dry run, if you will, so now I’m afraid I have something of a mess on my hands.",
|
6
|
+
"I can already taste those meaty leading man parts.",
|
7
|
+
"I just can't seem to get one in the can...",
|
8
|
+
"I will pack your mouth with your sweet, pink mouth with so much ice cream, you'll be the envy of every Jerry and Jane on the block.",
|
9
|
+
"Well I guess you could say I am buy-curious",
|
10
|
+
'I see you wasted no time filling my "seat hole"',
|
11
|
+
'Excuse me, do these effectively hide my thunder?',
|
12
|
+
'Perhaps I should call the hot cops and tell them to come up with a more nautical theme. Hot sailors. Better yet... Hot sea...',
|
13
|
+
'Ah yes, the Bob Loblaw Law Blog. You, sir, are a mouthful.',
|
14
|
+
"No, no. It's pronounced a-nal-ra-pist.",
|
15
|
+
"Okay, who'd like a banger in the mouth? Right, I forgot, here in the States, you call it a sausage in the mouth.",
|
16
|
+
'Michael, you are quite the cupid. You can stick an arrow in my buttocks any time. ',
|
17
|
+
'Oh really? Then have sex with this girl right now. Go on. Have some sex with her.',
|
18
|
+
'Let the great experiment begin!',
|
19
|
+
"Tobias, you blowhard.",
|
20
|
+
"Michael, you are not quite the ladies man I had pictured. Hopefully, we will remedy that when we are in the spa spreading body chocolate on each other. ",
|
21
|
+
"Boy, I sure feel like a Mary without a Peter and a Paul. ",
|
22
|
+
"I'm looking for something that says 'Dad likes leather'. ",
|
23
|
+
"I need to go take down the buffet and set up the leather pony. "]
|
24
|
+
|
25
|
+
quotes[rand(quotes.length)]
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
def self.help
|
30
|
+
"!blowhard - words of wisdom from Dr. Funke"
|
31
|
+
end
|
32
|
+
|
33
|
+
|
34
|
+
Linkbot::Plugin.register('blowhard', self,
|
35
|
+
{
|
36
|
+
:message => {:regex => /!blowhard/, :handler => :on_message, :help => :help},
|
37
|
+
:"direct-message" => {:regex => /!blowhard/, :handler => :on_message, :help => :help}
|
38
|
+
}
|
39
|
+
)
|
40
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
|
3
|
+
class Comic < Linkbot::Plugin
|
4
|
+
Linkbot::Plugin.register('comic', self,
|
5
|
+
{
|
6
|
+
:message => {:regex => Regexp.new('(?:!comic|!fffffffuuuuuuuuuuuu)(?: (\d+))?'), :handler => :on_message, :help => :help},
|
7
|
+
}
|
8
|
+
)
|
9
|
+
|
10
|
+
def self.on_message(message, matches)
|
11
|
+
times = matches[0] || "1"
|
12
|
+
times = times.to_i
|
13
|
+
messages = []
|
14
|
+
|
15
|
+
1.upto(times) do
|
16
|
+
|
17
|
+
# Brute force this mother
|
18
|
+
subreddit = "http://reddit.com/r/fffffffuuuuuuuuuuuu.json"
|
19
|
+
|
20
|
+
puts subreddit
|
21
|
+
doc = ActiveSupport::JSON.decode(open(subreddit, "Cookie" => "reddit_session=8390507%2C2011-03-22T07%3A06%3A44%2C2516dcc69a22ad297b9900cbde147b365203bbbb").read)
|
22
|
+
|
23
|
+
url = doc["data"]["children"][rand(doc["data"]["children"].length)]["data"]["url"]
|
24
|
+
|
25
|
+
# Check if it's an imgur link without an image extension
|
26
|
+
if url =~ /http:\/\/(www\.)?imgur\.com/ && !['jpg','png','gif'].include?(url.split('.').last)
|
27
|
+
# Fetch the imgur page and pull out the image
|
28
|
+
doc = Hpricot(open(url).read)
|
29
|
+
url = doc.search("img")[1]['src']
|
30
|
+
end
|
31
|
+
|
32
|
+
messages << url
|
33
|
+
end
|
34
|
+
return messages.join("\n")
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.help
|
38
|
+
"!comic - return a random fffffffuuuuuuuuuuuu comic"
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'hpricot'
|
3
|
+
require 'sqlite3'
|
4
|
+
require 'time'
|
5
|
+
|
6
|
+
class Dupe < Linkbot::Plugin
|
7
|
+
|
8
|
+
Linkbot::Plugin.register('dupe', self,
|
9
|
+
{
|
10
|
+
:message => {:regex => /!stats/, :handler => :on_message, :help => :help}
|
11
|
+
}
|
12
|
+
)
|
13
|
+
|
14
|
+
def self.on_message(message, matches)
|
15
|
+
rows = Linkbot.db.execute("select u.username,s.total,s.dupes,k.karma,u.showname from stats s, users u, karma k where u.user_id = s.user_id AND u.user_id = k.user_id order by k.karma desc")
|
16
|
+
mess = "Link stats:\n--------------------------\n"
|
17
|
+
|
18
|
+
#find the maximum length karma total
|
19
|
+
max = rows.collect { |row| row[1].to_s }.map(&:length).max
|
20
|
+
|
21
|
+
rows.each {|row|
|
22
|
+
username = (row[4].nil? || row[4] == '') ? row[0] : row[4]
|
23
|
+
dupe = row[2] == 1 ? 'dupe' : 'dupes'
|
24
|
+
mess = mess + sprintf("%#{max}d: #{username} (%d links, %d %s, %.2f%% new)\n", row[3], row[1], row[2], dupe, (row[1]/(row[1]+row[2]).to_f)*100)
|
25
|
+
}
|
26
|
+
mess
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.on_dupe(message, url, duped_user, duped_timestamp)
|
30
|
+
total,dupes = self.stats(message.user_id)
|
31
|
+
Linkbot.db.execute("update stats set dupes = #{dupes+1} where user_id='#{message.user_id}'")
|
32
|
+
res = Linkbot.db.execute("select username,showname from users where user_id='#{message.user_id}'")[0]
|
33
|
+
username = (res[1].nil? || res[1] == '') ? res[0] : res[1]
|
34
|
+
puts duped_timestamp
|
35
|
+
"DUPE: Previously posted by #{duped_user} #{::Util.ago_in_words(Time.now, Time.parse(duped_timestamp.to_s))}"
|
36
|
+
end
|
37
|
+
|
38
|
+
def self.on_newlink(message, url)
|
39
|
+
total,dupes = self.stats(message.user_id)
|
40
|
+
Linkbot.db.execute("update stats set total = #{total+1} where user_id='#{message.user_id}'")
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def self.stats(user_id)
|
45
|
+
total = 0
|
46
|
+
dupes = 0
|
47
|
+
rows = Linkbot.db.execute("select user_id,total,dupes from stats where user_id = '#{user_id}'")
|
48
|
+
if rows.empty?
|
49
|
+
Linkbot.db.execute("insert into stats (user_id,total,dupes) values ('#{user_id}', 0, 0)")
|
50
|
+
else
|
51
|
+
total = rows[0][1]
|
52
|
+
dupes = rows[0][2]
|
53
|
+
end
|
54
|
+
return total,dupes
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.help
|
58
|
+
"!stats - show all karma and links stats for linkchat participants"
|
59
|
+
end
|
60
|
+
|
61
|
+
if Linkbot.db.table_info('stats').empty?
|
62
|
+
Linkbot.db.execute('CREATE TABLE stats (user_id INTEGER, dupes INTEGER, total INTEGER)');
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
class Helper < Linkbot::Plugin
|
2
|
+
|
3
|
+
Linkbot::Plugin.register('help', self,
|
4
|
+
{
|
5
|
+
:message => {:regex => /!help/, :handler => :on_message},
|
6
|
+
:"direct-message" => {:regex => /!help/, :handler => :on_message}
|
7
|
+
}
|
8
|
+
)
|
9
|
+
|
10
|
+
def self.on_message(message, matches)
|
11
|
+
messages = []
|
12
|
+
Linkbot::Plugin.plugins.each {|k,v|
|
13
|
+
if(v[:handlers][message.type] && v[:handlers][message.type][:help])
|
14
|
+
messages << v[:ptr].send(v[:handlers][message.type][:help])
|
15
|
+
end
|
16
|
+
}
|
17
|
+
messages.sort! do |x,y|
|
18
|
+
x =~ /([A-Za-z]+)/
|
19
|
+
sort1 = $1
|
20
|
+
y =~ /([A-Za-z]+)/
|
21
|
+
sort2 = $1
|
22
|
+
sort1 <=> sort2
|
23
|
+
end
|
24
|
+
messages.join("\n")
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'uri'
|
3
|
+
|
4
|
+
class Image < Linkbot::Plugin
|
5
|
+
|
6
|
+
Linkbot::Plugin.register('image', self,
|
7
|
+
{
|
8
|
+
:message => {:regex => /!image(?: (.+))?/, :handler => :on_message, :help => :help}
|
9
|
+
}
|
10
|
+
)
|
11
|
+
|
12
|
+
def self.on_message(message, matches)
|
13
|
+
searchterm = matches[0]
|
14
|
+
if searchterm.nil?
|
15
|
+
doc = Hpricot(open("http://www.randomword.net").read)
|
16
|
+
searchterm = doc.search("#word h2").text.strip
|
17
|
+
end
|
18
|
+
doc = JSON.parse(open("http://ajax.googleapis.com/ajax/services/search/images?v=1.0&q=#{URI.encode(searchterm)}&rsz=8&safe=off", "Referer" => "http://lgscout.com").read)
|
19
|
+
if doc["responseData"]["results"].length > 0
|
20
|
+
doc["responseData"]["results"][rand(doc["responseData"]["results"].length)]["url"]
|
21
|
+
else
|
22
|
+
"No pictures found! Nuts!"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.help
|
27
|
+
"!image [searchity search] - Return a relevant picture"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'open-uri'
|
2
|
+
require 'hpricot'
|
3
|
+
|
4
|
+
class Imgur < Linkbot::Plugin
|
5
|
+
|
6
|
+
Linkbot::Plugin.register('imgur', self,
|
7
|
+
{
|
8
|
+
:message => {:regex => /!imgur/, :handler => :on_message, :help => :help},
|
9
|
+
:"direct-message" => {:regex => /!imgur/, :handler => :on_message, :help => :help}
|
10
|
+
}
|
11
|
+
)
|
12
|
+
|
13
|
+
def self.on_message(message, matches)
|
14
|
+
imgs = []
|
15
|
+
puts "loading images"
|
16
|
+
1.upto(3) do |x|
|
17
|
+
doc = Hpricot(open("http://imgur.com/gallery?p=#{x}").read)
|
18
|
+
imgs += doc.search("div[@class=post] a img").collect do |m|
|
19
|
+
m.attributes["src"].gsub("b.jpg", ".jpg")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
img = imgs[rand(imgs.length)]
|
23
|
+
|
24
|
+
img
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.help
|
28
|
+
"!imgur - return a random top picture"
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|