protolink 0.2.7 → 0.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/Gemfile +1 -0
  2. data/Gemfile.lock +12 -0
  3. data/README.markdown +15 -4
  4. data/example/chatbot.rb +24 -0
  5. data/example/create_and_subscribe.rb +5 -1
  6. data/example/linkbot/base_plugins.rb +71 -0
  7. data/example/linkbot/plugins/awwwyeah.rb +11 -0
  8. data/example/linkbot/plugins/blowhard.rb +40 -0
  9. data/example/linkbot/plugins/comic.rb +40 -0
  10. data/example/linkbot/plugins/dumb.rb +11 -0
  11. data/example/linkbot/plugins/dupe.rb.inactive +64 -0
  12. data/example/linkbot/plugins/face.rb +11 -0
  13. data/example/linkbot/plugins/fuuu.rb +12 -0
  14. data/example/linkbot/plugins/help.rb +26 -0
  15. data/example/linkbot/plugins/image.rb +30 -0
  16. data/example/linkbot/plugins/imgur.rb +31 -0
  17. data/example/linkbot/plugins/jason.rb +73 -0
  18. data/example/linkbot/plugins/karma.rb.inactive +75 -0
  19. data/example/linkbot/plugins/last.rb +40 -0
  20. data/example/linkbot/plugins/links.rb.inactive +41 -0
  21. data/example/linkbot/plugins/log.rb +17 -0
  22. data/example/linkbot/plugins/okay.rb +11 -0
  23. data/example/linkbot/plugins/onion.rb +19 -0
  24. data/example/linkbot/plugins/popcorn.rb +32 -0
  25. data/example/linkbot/plugins/qwantz.rb +29 -0
  26. data/example/linkbot/plugins/search.rb +32 -0
  27. data/example/linkbot/plugins/shutup.rb +11 -0
  28. data/example/linkbot/plugins/slap.rb +15 -0
  29. data/example/linkbot/plugins/snap.rb +18 -0
  30. data/example/linkbot/plugins/stab.rb +12 -0
  31. data/example/linkbot/plugins/store.rb +71 -0
  32. data/example/linkbot/plugins/store_help.rb +22 -0
  33. data/example/linkbot/plugins/swanson.rb +41 -0
  34. data/example/linkbot/plugins/titles.rb +34 -0
  35. data/example/linkbot/plugins/translate.rb +21 -0
  36. data/example/linkbot/plugins/tsa.rb +22 -0
  37. data/example/linkbot/plugins/twss.rb +20 -0
  38. data/example/linkbot/plugins/urban.rb +27 -0
  39. data/example/linkbot/util.rb +28 -0
  40. data/lib/protolink.rb +4 -0
  41. data/lib/protolink/channel.rb +4 -0
  42. data/lib/protolink/flash_connection.rb +47 -0
  43. data/lib/protolink/proto_socket.rb +33 -0
  44. data/lib/protolink/protonet.rb +18 -3
  45. data/lib/protolink/version.rb +1 -1
  46. data/test/all_tests.rb +2 -2
  47. metadata +41 -4
@@ -0,0 +1,22 @@
1
+ class StoreHelp < Linkbot::Plugin
2
+ def self.on_store(args)
3
+ mymsg = nil
4
+
5
+ if args.length > 0
6
+ Linkbot::Plugin.plugins.each {|k,v|
7
+ if v[:handlers][:"linkbot-store"] && v[:handlers][:"linkbot-store"][:help] && v[:handlers][:"linkbot-store"][:regex].match(args[0])
8
+ mymsg = v[:ptr].send(v[:handlers][:"linkbot-store"][:help])
9
+ end
10
+ }
11
+ end
12
+
13
+ mymsg
14
+ end
15
+
16
+
17
+ Linkbot::Plugin.register('store_help', self,
18
+ {
19
+ :"linkbot-store" => {:regex => /^help$/, :handler => :on_store},
20
+ }
21
+ )
22
+ end
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ class Swanson < Linkbot::Plugin
4
+ def self.on_message(message, matches)
5
+ quotes = [
6
+ "http://www.pajiba.com/image/ron-dancing-animated.gif",
7
+ "http://28.media.tumblr.com/tumblr_lgl0ieJ0Z01qzkiy8o1_400.jpg",
8
+ "http://www.randomblog.org/wp-content/uploads/2011/02/Ron-Swanson-Pyramid-e1297006038780.jpg",
9
+ "I have been developing the Swanson Pyramid of Greatness for years. It's a perfectly calibrated recipe for maximum personal achievement. Categories include: Capitalism, God's way of determining who is smart, and who is poor. Crying, acceptable at funerals and the Grand Canyon. Rage. Poise. Property rights. Fish, for sport only, not for meat. Fish meat is practically a vegetable.",
10
+ "The less I know about other people's affairs, the happier I am. I'm not interested in caring about people. I once worked with a guy for three years and never learned his name. Best friend I ever had. We still never talk sometimes.",
11
+ "Now, I know I'm not going to find somebody that's both aggressively mean and apathetic. April really is the whole package.",
12
+ "You had me at meat tornado.",
13
+ "I'm surrounded by a lot of women in this department. And that includes the men.",
14
+ "When I walked in this morning I saw that the flag was at half mast, I though, 'All right, another bureaucrat ate it!' And then I saw it was Lil' Sebastian. Half mast is too high. Show some damn respect.",
15
+ "I am submitting this menu from a Pawnee institution, J.J.'s Diner. Home of the world's best breakfast dish: The Four Horsemeals of the Eggporkalypse.",
16
+ "You may have thought you heard me say I wanted a lot of bacon and eggs, but what I said was: Give me all the bacon and eggs you have.",
17
+ "(On fishing) It's like yoga, except I still get to kill something.",
18
+ "Encapsulate the spirit of melancholy. Easy. Boom, a sad desk. Boom, sad wall. It's art. Anything is anything.",
19
+ "I am off to have a mid-morning pre-lunch with my lady friend, but I will be back in time for lunch.",
20
+ "The key to burning an ex-wife effigy is to dip it in paraffin wax and then toss the flaming bottle of isopropyl alcohol from a safe distance. Do not stand too close when you light an ex-wife effigy.",
21
+ "It's never too early to learn that the government is a greedy piglet that suckles on a taxpayer's teet until they have sore, chapped nipples. I'm gonna need a different metaphor to give this nine year old.",
22
+ "Leslie, you need to understand that we are headed to the most special place on earth. When I'm done eating a Mulligan's meal, for weeks afterwards there are flecks of meat in my mustache and I refuse to clean it because every now and then a piece of meat will fall into my mouth.",
23
+ "(His museum speech) Shut up. And look at me. Welcome to Visions of Nature. This room has several paintings in it. Some are big and some are small. People did them and they are here now. I believe after this is over they will be hung in government buildings. Why the government is involved in an art show is beyond me. I also think it's pointless for a human to paint scenes of nature when they can go outside and stand in it.",
24
+ "The whole thing is a scam. Birthdays were invented by Hallmark to sell cards.",
25
+ "I won't publicly endorse a product unless I use it exclusively. My only official recommendations are U.S. Army issued mustache trimmers, Morton's salt, and the C.R. Lawrence Fein two inch axe-style scraper oscillating knife blade."
26
+ ]
27
+ quotes[rand(quotes.length)]
28
+ end
29
+
30
+ def self.help
31
+ "!swanson - The one and only, Ron Swanson"
32
+ end
33
+
34
+
35
+ Linkbot::Plugin.register('swanson', self,
36
+ {
37
+ :message => {:regex => /!swanson/, :handler => :on_message, :help => :help},
38
+ :"direct-message" => {:regex => /!swanson/, :handler => :on_message, :help => :help}
39
+ }
40
+ )
41
+ end
@@ -0,0 +1,34 @@
1
+ class Titles < Linkbot::Plugin
2
+ def self.on_store(args)
3
+ mymsg = nil
4
+
5
+ if args.length > 1
6
+ target_user = args.shift
7
+ rows = Linkbot.db.execute("select username,showname from users where username='#{target_user}'")
8
+ if rows.length == 0
9
+ raise StoreError.new("Unknown user")
10
+ else
11
+ old_username = (rows[0][1].nil? || rows[0][1] == '') ? rows[0][0] : rows[0][1]
12
+ new_username = args.join(" ")
13
+ Linkbot.db.execute("update users set showname='#{new_username}' where username='#{target_user}'")
14
+ mymsg = "'#{old_username}' is now known as '#{new_username}'"
15
+ end
16
+ end
17
+
18
+ mymsg
19
+ end
20
+
21
+ def self.cost
22
+ 50
23
+ end
24
+
25
+ def self.advertisement
26
+ "name (username) (new name): Change how a user's name appears in any linkbot command."
27
+ end
28
+
29
+ Linkbot::Plugin.register('titles', self,
30
+ {
31
+ :"linkbot-store" => {:regex => /^name$/, :handler => :on_store},
32
+ }
33
+ )
34
+ end
@@ -0,0 +1,21 @@
1
+ require 'net/http'
2
+ require 'uri'
3
+ require 'cgi'
4
+
5
+ class Translate < Linkbot::Plugin
6
+ def self.on_message(message, matches)
7
+ res = Net::HTTP.post_form(URI.parse('http://www.cs.utexas.edu/users/jbc/bork/bork.cgi'),
8
+ {'input'=> CGI.unescapeHTML(message_history[1]['body']), 'type'=>'chef'})
9
+ CGI::unescape(res.body.to_s.gsub("&epus;","'"))
10
+ end
11
+
12
+ def self.help
13
+ "!translate - Trunslete-a zee lest messege-a"
14
+ end
15
+
16
+ Linkbot::Plugin.register('translate', self,
17
+ {
18
+ :message => {:regex => /!translate/, :handler => :on_message, :help => :help}
19
+ }
20
+ )
21
+ end
@@ -0,0 +1,22 @@
1
+ class Tsa < Linkbot::Plugin
2
+ Linkbot::Plugin.register('tsa', self,
3
+ {
4
+ :message => {:regex => Regexp.new('tsa', 'g'), :handler => :on_message}
5
+ }
6
+ )
7
+
8
+ def self.on_message(message, matches)
9
+ messages = [
10
+ "I'm going to touch your balls with the back of my hand",
11
+ "We have an opt-out!",
12
+ "TSA: the McDonalds workers of the government",
13
+ "Security Theater Professionals",
14
+ "Sir, you've been added to the \"domestic extremists\" list",
15
+ "Not all parts of the government are accountable to the public, especially the TSA",
16
+ "Your junk is safe in our hands",
17
+ "It's not a grope, it's a freedom pat",
18
+ "We handle more packages than UPS",
19
+ ]
20
+ messages[rand(messages.length)]
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ require 'twss'
2
+
3
+ class Twss < Linkbot::Plugin
4
+ def self.on_message(message, matches)
5
+ TWSS.threshold = 2.0 #lower = 'better'
6
+ if TWSS(message.body) and 1 < 0
7
+ "That's what she said"
8
+ else
9
+ ""
10
+ end
11
+ end
12
+
13
+ Linkbot::Plugin.register('twss', self,
14
+ {
15
+ :message => {:handler => :on_message}
16
+ }
17
+ )
18
+ end
19
+
20
+
@@ -0,0 +1,27 @@
1
+ class Define < Linkbot::Plugin
2
+ def self.on_message(message, match)
3
+ word = URI.escape(match[0])
4
+ doc = Hpricot(open("http://www.urbandictionary.com/define.php?term=#{word}").read)
5
+ definition = doc.search("#entries td div[@class=definition]")
6
+ if definition.empty?
7
+ message = "No definition for '#{match[0]}' found"
8
+ else
9
+ definition = definition[0].inner_html.gsub("<br />", "\n")
10
+ definition = Sanitize.clean(definition)
11
+ message = "#{match[0]}: #{definition}"
12
+ end
13
+
14
+ message
15
+ end
16
+
17
+ def self.help
18
+ "!define (word) - use a dictionary, foo"
19
+ end
20
+
21
+ Linkbot::Plugin.register('urban', self,
22
+ {
23
+ :message => {:regex => /!define (.*)/, :handler => :on_message, :help => :help},
24
+ :"direct-message" => {:regex => /!define (.*)/, :handler => :on_message, :help => :help}
25
+ }
26
+ )
27
+ end
@@ -0,0 +1,28 @@
1
+ module Util
2
+ def self.ago_in_words(time1, time2)
3
+ diff = time1.to_i - time2.to_i
4
+ ago = ''
5
+ if diff == 1
6
+ ago = "#{diff} second ago"
7
+ elsif diff < 60
8
+ ago = "#{diff} seconds ago"
9
+ elsif diff < 120
10
+ ago = "a minute ago"
11
+ elsif diff < 3600
12
+ ago = "#{diff.to_i / 60} minutes ago"
13
+ elsif diff < 7200
14
+ ago = "an hour ago"
15
+ elsif diff < 86400
16
+ ago = "#{diff.to_i / 3600} hours ago"
17
+ elsif diff < 172800
18
+ ago = "yesterday"
19
+ elsif diff < 604800
20
+ ago = "#{diff.to_i / 86400} days ago"
21
+ elsif diff < 1209600
22
+ ago = "last week"
23
+ else
24
+ ago = "#{diff.to_i / 604800} weeks ago"
25
+ end
26
+ ago
27
+ end
28
+ end
@@ -1,9 +1,13 @@
1
+ require 'eventmachine'
2
+ require 'protolink/flash_connection'
3
+ require 'protolink/proto_socket'
1
4
  require 'protolink/protonet'
2
5
  require 'protolink/channel'
3
6
  require 'protolink/user'
4
7
  require 'protolink/listen'
5
8
  require 'protolink/node'
6
9
 
10
+
7
11
  module Protolink
8
12
  class Error < StandardError; end
9
13
  class SSLRequiredError < Error; end
@@ -28,6 +28,10 @@ module Protolink
28
28
  User.new(connection, user)
29
29
  end
30
30
  end
31
+
32
+ def listen
33
+
34
+ end
31
35
 
32
36
  protected
33
37
 
@@ -0,0 +1,47 @@
1
+ require 'json'
2
+
3
+ class FlashConnection < EventMachine::Connection
4
+ def initialize
5
+ @buffer = ''
6
+
7
+ set_comm_inactivity_timeout 60
8
+ end
9
+ # JSON packets
10
+ def send_json json
11
+ send_data json.to_json + "\0"
12
+ end
13
+
14
+ # Null-terminated lines
15
+ def send_line line
16
+ send_data line + "\0"
17
+ end
18
+
19
+ def receive_line line
20
+ receive_json JSON.parse(line)
21
+ rescue JSON::ParserError
22
+ log "JSON parsing error"
23
+ end
24
+
25
+ # Raw bytes
26
+ def receive_data data
27
+ @buffer += data
28
+
29
+ while @buffer.include? "\0"
30
+ packet = @buffer[0, @buffer.index("\0")]
31
+ @buffer = @buffer[(@buffer.index("\0")+1)..-1]
32
+
33
+ receive_line packet
34
+ end
35
+ rescue => ex
36
+ p ex, ex.backtrace
37
+ end
38
+
39
+ # TODO: redundant code
40
+ def log text
41
+ puts "#{self}: #{text}" if Rails.env != "production" || $DEBUG
42
+ end
43
+
44
+ def to_s
45
+ "connection #{inspect}"
46
+ end
47
+ end
@@ -0,0 +1,33 @@
1
+ class ProtoSocket < FlashConnection
2
+
3
+ def initialize(connection, message_callback)
4
+ @connection = connection
5
+ @message_callback = message_callback
6
+ super()
7
+ end
8
+
9
+ def connection_completed
10
+ token = @connection.current_user.communication_token
11
+
12
+ send_json :operation => 'authenticate',
13
+ :payload => {:type => 'web', :user_id => @connection.current_user.id, :token => token}
14
+
15
+ periodic_ping
16
+ end
17
+
18
+ def receive_json(json)
19
+ @message_callback.call(json)
20
+ end
21
+
22
+ def periodic_ping
23
+ @ping ||= EventMachine.add_periodic_timer 30 do
24
+ # log "sending ping"
25
+ send_json :operation => 'ping'
26
+ end
27
+ end
28
+
29
+ def unbind
30
+ EventMachine::cancel_timer @ping
31
+ end
32
+
33
+ end
@@ -25,11 +25,20 @@ module Protolink
25
25
  if proxy
26
26
  clazz.http_proxy(proxy[:uri], proxy[:port])
27
27
  end
28
- clazz.new
28
+ clazz.new(username)
29
29
  end
30
30
 
31
31
  # CHANNELS
32
-
32
+
33
+ def initialize(username)
34
+ @current_user_name = username
35
+ super()
36
+ end
37
+
38
+ def current_user
39
+ @current_user ||= find_user_by_login(@current_user_name)
40
+ end
41
+
33
42
  # Get an array of all the available channels
34
43
  def channels
35
44
  get('/api/v1/channels').map do |channel|
@@ -137,7 +146,7 @@ module Protolink
137
146
  end
138
147
 
139
148
  def destroy_listen(user_id, channel_id)
140
- channel_query = channel_id.match("-") ? {:channel_uuid => channel_id} : {:channel_id => channel_id}
149
+ channel_query = channel_id.to_s.match("-") ? {:channel_uuid => channel_id} : {:channel_id => channel_id}
141
150
  delete('/api/v1/listens', :body => {:user_id => user_id}.merge(channel_query) )
142
151
  end
143
152
 
@@ -151,6 +160,12 @@ module Protolink
151
160
  Node.new(self, response) if response
152
161
  end
153
162
 
163
+ def socket(&blk)
164
+ EventMachine.run {
165
+ EventMachine.connect URI.parse(self.class.base_uri).host, 5000, ProtoSocket, self, blk
166
+ }
167
+ end
168
+
154
169
  [:get, :post, :update, :delete].each do |method|
155
170
  class_eval <<-EOS
156
171
  def #{method}(uri, options = {})
@@ -1,3 +1,3 @@
1
1
  module Protolink
2
- VERSION = '0.2.7' unless defined?(::Protolink::VERSION)
2
+ VERSION = '0.2.8' unless defined?(::Protolink::VERSION)
3
3
  end
@@ -8,8 +8,8 @@ require 'ruby-debug'
8
8
  Debugger.start
9
9
  # change this if you need to connect to another server
10
10
  PTN_SERVER = "http://localhost:3000"
11
- PTN_USER = "test_suite"
12
- PTN_PASS = "testtest"
11
+ PTN_USER = "admin"
12
+ PTN_PASS = "admin"
13
13
 
14
14
  class TestAll < Test::Unit::TestCase
15
15
 
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: protolink
3
3
  version: !ruby/object:Gem::Version
4
- hash: 25
4
+ hash: 7
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 7
10
- version: 0.2.7
9
+ - 8
10
+ version: 0.2.8
11
11
  platform: ruby
12
12
  authors:
13
13
  - "Bj\xC3\xB6rn B. Dorra"
@@ -16,7 +16,7 @@ autorequire:
16
16
  bindir: bin
17
17
  cert_chain: []
18
18
 
19
- date: 2011-10-11 00:00:00 +02:00
19
+ date: 2011-10-26 00:00:00 +02:00
20
20
  default_executable:
21
21
  dependencies:
22
22
  - !ruby/object:Gem::Dependency
@@ -64,11 +64,48 @@ files:
64
64
  - Gemfile.lock
65
65
  - README.markdown
66
66
  - Rakefile
67
+ - example/chatbot.rb
67
68
  - example/create_and_subscribe.rb
69
+ - example/linkbot/base_plugins.rb
70
+ - example/linkbot/plugins/awwwyeah.rb
71
+ - example/linkbot/plugins/blowhard.rb
72
+ - example/linkbot/plugins/comic.rb
73
+ - example/linkbot/plugins/dumb.rb
74
+ - example/linkbot/plugins/dupe.rb.inactive
75
+ - example/linkbot/plugins/face.rb
76
+ - example/linkbot/plugins/fuuu.rb
77
+ - example/linkbot/plugins/help.rb
78
+ - example/linkbot/plugins/image.rb
79
+ - example/linkbot/plugins/imgur.rb
80
+ - example/linkbot/plugins/jason.rb
81
+ - example/linkbot/plugins/karma.rb.inactive
82
+ - example/linkbot/plugins/last.rb
83
+ - example/linkbot/plugins/links.rb.inactive
84
+ - example/linkbot/plugins/log.rb
85
+ - example/linkbot/plugins/okay.rb
86
+ - example/linkbot/plugins/onion.rb
87
+ - example/linkbot/plugins/popcorn.rb
88
+ - example/linkbot/plugins/qwantz.rb
89
+ - example/linkbot/plugins/search.rb
90
+ - example/linkbot/plugins/shutup.rb
91
+ - example/linkbot/plugins/slap.rb
92
+ - example/linkbot/plugins/snap.rb
93
+ - example/linkbot/plugins/stab.rb
94
+ - example/linkbot/plugins/store.rb
95
+ - example/linkbot/plugins/store_help.rb
96
+ - example/linkbot/plugins/swanson.rb
97
+ - example/linkbot/plugins/titles.rb
98
+ - example/linkbot/plugins/translate.rb
99
+ - example/linkbot/plugins/tsa.rb
100
+ - example/linkbot/plugins/twss.rb
101
+ - example/linkbot/plugins/urban.rb
102
+ - example/linkbot/util.rb
68
103
  - lib/protolink.rb
69
104
  - lib/protolink/channel.rb
105
+ - lib/protolink/flash_connection.rb
70
106
  - lib/protolink/listen.rb
71
107
  - lib/protolink/node.rb
108
+ - lib/protolink/proto_socket.rb
72
109
  - lib/protolink/protonet.rb
73
110
  - lib/protolink/user.rb
74
111
  - lib/protolink/version.rb