hiptail 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,78 @@
1
+ module HipTail
2
+ module Util
3
+ # Build capability object.
4
+ # @param [Hash] params
5
+ # @option params [String] :key Identical key for add-on
6
+ # @option params [String] :name Add-on name
7
+ # @option params [String] :base_url Base URL for add-on
8
+ # @option params [String] :capability_url URL for capability
9
+ # @option params [String] :webhook_url URL for event webhook
10
+ # @option params [String] :installed_url URL for installed / uninstalled event webhook
11
+ # @option params [String] :description (same as :name) Add-on description (optional)
12
+ # @option params [String] :vendor_name (same as :name) Vendor name (optional)
13
+ # @option params [String] :vendor_url (same as :base_url) Vendor URL (optional)
14
+ # @option params [String] :homepage_url (same as :base_url) Homepage (optional)
15
+ # @option params [String] :sender_name (same as :name) Name of notification sender (optional)
16
+ # @option params [String] :allow_global (true) Allow global installation (optional)
17
+ # @option params [String] :allow_room (true) Allow room installation (optional)
18
+ # @option params [String] :message_filter Room message filter regexp (optional)
19
+ def create_capability(params)
20
+ requireds = %w( key name
21
+ base_url capability_url webhook_url installed_url )
22
+ missings = requireds.select { |k| ! params.include?(k.to_sym) }
23
+ if missings.length > 0
24
+ raise "missing parameters: " + missings.join(%q{, })
25
+ end
26
+
27
+ capability = {
28
+ key: params[:key],
29
+ name: params[:name],
30
+ description: params[:description] || params[:name],
31
+ vendor: {
32
+ name: params[:vendor_name] || params[:name],
33
+ url: (params[:vendor_url] || params[:base_url]).to_s,
34
+ },
35
+ links: {
36
+ self: params[:capability_url].to_s,
37
+ homepage: (params[:homepage_url] || params[:base_url]).to_s,
38
+ },
39
+ capabilities: {
40
+ webhook: [],
41
+ hipchatApiConsumer: {
42
+ scopes: %w( send_notification send_message admin_room view_group ),
43
+ fromName: params[:sender_name] || params[:name],
44
+ },
45
+ installable: {
46
+ allowGlobal: params.include?(:allow_global) ? params[:allow_global] : true,
47
+ allowRoom: params.include?(:allow_room) ? params[:allow_room] : true,
48
+ callbackUrl: params[:installed_url].to_s,
49
+ }
50
+ },
51
+ }
52
+
53
+ event_names = %w( room_notification room_topic_change
54
+ room_enter room_exit )
55
+ webhook_url = params[:webhook_url].to_s
56
+
57
+ capability[:capabilities][:webhook] = event_names.map { |key|
58
+ {
59
+ name: key,
60
+ event: key,
61
+ url: webhook_url,
62
+ }
63
+ }
64
+ message_webhook = {
65
+ name: 'room_message',
66
+ event: 'room_message',
67
+ url: webhook_url,
68
+ }
69
+ if params[:message_filter]
70
+ message_webhook[:pattern] = params[:message_filter].to_s
71
+ end
72
+ capability[:capabilities][:webhook] << message_webhook
73
+
74
+ capability
75
+ end
76
+ module_function :create_capability
77
+ end
78
+ end
@@ -0,0 +1,3 @@
1
+ module HipTail
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,99 @@
1
+ require 'json'
2
+ require 'uri'
3
+ require 'hiptail/util'
4
+
5
+ module HipTail
6
+ module Web; end
7
+
8
+ class Web::Handler
9
+ # @return [HipTail::Manager] Returns HipTail::Manager.
10
+ attr_reader :manager
11
+
12
+ # @param [HipTail::Manager] manager
13
+ def initialize(manager)
14
+ @manager = manager
15
+ end
16
+
17
+ # Handles installing request.
18
+ # @param [Rack::Request] request
19
+ # @return [Array] Rack response.
20
+ def handle_install(request)
21
+ request.body.rewind
22
+ @manager.handle_install(JSON.parse(request.body.read))
23
+ create_response({})
24
+ end
25
+
26
+ # Handles uninstalling request.
27
+ # @note Uninstall event will be fired after uninstallation on the server.
28
+ # So you cannot use oauth information to do something (e.g. sending notification) on uninstallation phase.
29
+ # @param [Rack::Request] request
30
+ # @param [String] oauth_id Corresponding OAuth ID
31
+ # @return [Array] Rack response.
32
+ def handle_uninstall(request, oauth_id)
33
+ @manager.handle_uninstall(oauth_id)
34
+ create_response({})
35
+ end
36
+
37
+ # Handles events (room_message, room_enter, etc.).
38
+ # @param [Rack::Request] request
39
+ # @return [Array] Rack response.
40
+ def handle_event(request)
41
+ request.body.rewind
42
+ @manager.handle_event(JSON.parse(request.body.read))
43
+ create_response({})
44
+ end
45
+
46
+ # Handles retrieving capability request.
47
+ # @param [Rack::Request] request
48
+ # @param [Hash] params Capability parameters
49
+ # @option params [String] :key Identical key for add-on
50
+ # @option params [String] :name Add-on name
51
+ # @option params [String] :base_url Base URL for add-on
52
+ # @option params [String] :capability_url URL for capability
53
+ # @option params [String] :webhook_url URL for event webhook
54
+ # @option params [String] :installed_url URL for installed / uninstalled event webhook
55
+ # @option params [String] :description (same as :name) Add-on description (optional)
56
+ # @option params [String] :vendor_name (same as :name) Vendor name (optional)
57
+ # @option params [String] :vendor_url (same as :base_url) Vendor URL (optional)
58
+ # @option params [String] :homepage_url (same as :base_url) Homepage (optional)
59
+ # @option params [String] :sender_name (same as :name) Name of notification sender (optional)
60
+ # @option params [String] :allow_global (true) Allow global installation (optional)
61
+ # @option params [String] :allow_room (true) Allow room installation (optional)
62
+ # @option params [String] :message_filter Room message filter regexp (optional)
63
+ # @return [Array] Rack response.
64
+ def handle_capability(request, params)
65
+ requireds = %w( key name
66
+ webhook_path installed_path )
67
+ missings = requireds.select { |k| ! params.include?(k.to_sym) }
68
+ if missings.length > 0
69
+ raise "missing parameters: " + missings.join(%q{, })
70
+ end
71
+ params = params.dup
72
+
73
+ params[:capability_url] = request.url.to_s
74
+
75
+ base_url = URI.parse(request.url).merge(params[:base_path] || '/')
76
+ params[:base_url] = base_url.to_s
77
+
78
+ params[:webhook_url] = base_url.merge('./' + params[:webhook_path])
79
+ params[:installed_url] = base_url.merge('./' + params[:installed_path])
80
+
81
+ capability = HipTail::Util::create_capability(params)
82
+ create_response(capability)
83
+ end
84
+
85
+ # @param [Hash] data
86
+ # @param [Integer] status (200)
87
+ def create_response(data, status = 200)
88
+ body = JSON.generate(data)
89
+
90
+ body.gsub!(/[\u{007f}-\u{10ffff}]+/) { |match| match.unpack("U*").map! { |i| "\\u#{i.to_s(16)}" }.join }
91
+
92
+ headers = {
93
+ 'Content-Type' => 'application/json; charset=UTF-8',
94
+ 'Content-Length' => body.bytesize.to_s,
95
+ }
96
+ return [ status, headers, [ body ] ]
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,100 @@
1
+ require 'uri'
2
+ require 'rack'
3
+
4
+ require 'hiptail/web/handler'
5
+
6
+ module HipTail
7
+ module Web; end
8
+
9
+ class Web::RackApp
10
+ # @return [HipTail::Manager] Returns HipTail::Manager.
11
+ attr_reader :manager
12
+
13
+ # @param [Hash] params Capability parameters (and manager)
14
+ # @option params [HipTail::Manager] :manager HipTail::Manager instance (optional)
15
+ # @option params [String] :key Identical key for add-on
16
+ # @option params [String] :name Add-on name
17
+ # @option params [String] :base_url Base URL for add-on
18
+ # @option params [String] :capability_url URL for capability
19
+ # @option params [String] :webhook_url URL for event webhook
20
+ # @option params [String] :installed_url URL for installed / uninstalled event webhook
21
+ # @option params [String] :description (same as :name) Add-on description (optional)
22
+ # @option params [String] :vendor_name (same as :name) Vendor name (optional)
23
+ # @option params [String] :vendor_url (same as :base_url) Vendor URL (optional)
24
+ # @option params [String] :homepage_url (same as :base_url) Homepage (optional)
25
+ # @option params [String] :sender_name (same as :name) Name of notification sender (optional)
26
+ # @option params [String] :allow_global (true) Allow global installation (optional)
27
+ # @option params [String] :allow_room (true) Allow room installation (optional)
28
+ # @option params [String] :message_filter Room message filter regexp (optional)
29
+ def initialize(params)
30
+ params = params.dup
31
+ @manager = params.delete(:manager) || Manager.new
32
+ @handler = Web::Handler.new(@manager)
33
+
34
+ params[:base_path] ||= '/'
35
+ params[:webhook_path] ||= '/event'
36
+ params[:installed_path] ||= '/install'
37
+ params[:capability_path] ||= '/cap'
38
+ @capability_params = params
39
+
40
+ base_url = URI.parse('http://example.com/').merge(params[:base_path])
41
+ path = {
42
+ :base => base_url.request_uri,
43
+ }
44
+ [ :webhook, :installed, :capability ].each do |key|
45
+ path[key] = base_url.merge('./' + params["#{key}_path".to_sym]).request_uri
46
+ end
47
+
48
+ @regex = {}
49
+ @regex[:capability] = %r{\A #{Regexp.escape(path[:capability])} \z}xm
50
+ @regex[:event] = %r{\A #{Regexp.escape(path[:webhook])} \z}xm
51
+
52
+ @regex[:install] = %r{\A #{Regexp.escape(path[:installed])} \z}xm
53
+ @regex[:uninstall] = %r{\A #{Regexp.escape(path[:installed])} / ([-0-9a-fA-F]+) \z}xm
54
+ end
55
+
56
+ def call(env)
57
+ req = Rack::Request.new(env)
58
+
59
+ case req.path_info
60
+ when @regex[:capability]
61
+ if req.get?
62
+ return on_capability(req)
63
+ end
64
+ when @regex[:event]
65
+ if req.post?
66
+ return on_event(req)
67
+ end
68
+ when @regex[:install]
69
+ if req.post?
70
+ return on_install(req)
71
+ end
72
+ when @regex[:uninstall]
73
+ if req.delete?
74
+ return on_uninstall(req, $1)
75
+ end
76
+ end
77
+
78
+ return @handler.create_response({}, 404)
79
+ end
80
+
81
+ private
82
+
83
+ def on_capability(request)
84
+ @capability_cached ||= @handler.handle_capability(request, @capability_params)
85
+ @capability_cached
86
+ end
87
+
88
+ def on_event(request)
89
+ @handler.handle_event(request)
90
+ end
91
+
92
+ def on_install(request)
93
+ @handler.handle_install(request)
94
+ end
95
+
96
+ def on_uninstall(request, oauth_id)
97
+ @handler.handle_uninstall(request, oauth_id)
98
+ end
99
+ end
100
+ end
data/lib/hiptail.rb ADDED
@@ -0,0 +1,9 @@
1
+ require 'hiptail/version'
2
+ require 'hiptail/atom'
3
+ require 'hiptail/event'
4
+ require 'hiptail/authority'
5
+ require 'hiptail/authority/provider'
6
+ require 'hiptail/manager'
7
+ require 'hiptail/web/handler'
8
+ require 'hiptail/web/rack_app'
9
+ require 'hiptail/util'
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hiptail
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - ITO Nobuaki
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-09-22 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rack
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: oauth2
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.7'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.7'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rake
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '10.0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '10.0'
69
+ description: HipChat Add-on Framework
70
+ email:
71
+ - daydream.trippers@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - Gemfile
77
+ - LICENSE.txt
78
+ - README.md
79
+ - Rakefile
80
+ - examples/integrate_sinatra/Gemfile
81
+ - examples/integrate_sinatra/README.md
82
+ - examples/integrate_sinatra/app.rb
83
+ - examples/simple_rack_app_1/Gemfile
84
+ - examples/simple_rack_app_1/README.md
85
+ - examples/simple_rack_app_1/config.ru
86
+ - examples/simple_rack_app_2/Gemfile
87
+ - examples/simple_rack_app_2/README.md
88
+ - examples/simple_rack_app_2/app.rb
89
+ - examples/simple_rack_app_2/config.ru
90
+ - hiptail.gemspec
91
+ - lib/hiptail.rb
92
+ - lib/hiptail/atom.rb
93
+ - lib/hiptail/authority.rb
94
+ - lib/hiptail/authority/provider.rb
95
+ - lib/hiptail/authority/sqlite3_provider.rb
96
+ - lib/hiptail/event.rb
97
+ - lib/hiptail/manager.rb
98
+ - lib/hiptail/util.rb
99
+ - lib/hiptail/version.rb
100
+ - lib/hiptail/web/handler.rb
101
+ - lib/hiptail/web/rack_app.rb
102
+ homepage: https://github.com/dayflower/hiptail
103
+ licenses:
104
+ - MIT
105
+ metadata: {}
106
+ post_install_message:
107
+ rdoc_options: []
108
+ require_paths:
109
+ - lib
110
+ required_ruby_version: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '0'
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 2.2.2
123
+ signing_key:
124
+ specification_version: 4
125
+ summary: HipChat Add-on Framework
126
+ test_files: []