hiptail 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.
@@ -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: []