octospy 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +23 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +58 -0
  8. data/Rakefile +4 -0
  9. data/bin/octospy +6 -0
  10. data/lib/cinch/plugins/management.rb +91 -0
  11. data/lib/cinch/plugins/octospy/job.rb +97 -0
  12. data/lib/cinch/plugins/octospy/recording.rb +101 -0
  13. data/lib/cinch/plugins/octospy.rb +68 -0
  14. data/lib/octospy/configurable.rb +49 -0
  15. data/lib/octospy/extensions/string.rb +39 -0
  16. data/lib/octospy/octokit/client.rb +9 -0
  17. data/lib/octospy/parser/download.rb +13 -0
  18. data/lib/octospy/parser/gist.rb +20 -0
  19. data/lib/octospy/parser/issue.rb +43 -0
  20. data/lib/octospy/parser/organization.rb +22 -0
  21. data/lib/octospy/parser/pull_request.rb +32 -0
  22. data/lib/octospy/parser/repository.rb +80 -0
  23. data/lib/octospy/parser/user.rb +37 -0
  24. data/lib/octospy/parser/wiki.rb +19 -0
  25. data/lib/octospy/parser.rb +117 -0
  26. data/lib/octospy/recordable/channel.rb +23 -0
  27. data/lib/octospy/recordable/repo.rb +16 -0
  28. data/lib/octospy/recordable.rb +26 -0
  29. data/lib/octospy/shortener.rb +48 -0
  30. data/lib/octospy/version.rb +3 -0
  31. data/lib/octospy/worker.rb +48 -0
  32. data/lib/octospy.rb +55 -0
  33. data/octospy.gemspec +37 -0
  34. data/spec/fixtures/commit_comment_event.json +59 -0
  35. data/spec/fixtures/create_event.json +21 -0
  36. data/spec/fixtures/delete_event.json +23 -0
  37. data/spec/fixtures/follow_event.json +48 -0
  38. data/spec/fixtures/fork_event.json +139 -0
  39. data/spec/fixtures/gist_event.json +27 -0
  40. data/spec/fixtures/gollum_event.json +30 -0
  41. data/spec/fixtures/issue_comment_event.json +97 -0
  42. data/spec/fixtures/issues_event.json +70 -0
  43. data/spec/fixtures/member_event.json +39 -0
  44. data/spec/fixtures/public_event.json +16 -0
  45. data/spec/fixtures/pull_request_event.json +400 -0
  46. data/spec/fixtures/pull_request_review_comment_event.json +73 -0
  47. data/spec/fixtures/push_event.json +35 -0
  48. data/spec/fixtures/team_add_event.json +51 -0
  49. data/spec/fixtures/watch_event.json +23 -0
  50. data/spec/helper.rb +79 -0
  51. data/spec/octospy/extensions/string_spec.rb +84 -0
  52. data/spec/octospy/parser/download_spec.rb +9 -0
  53. data/spec/octospy/parser/gist_spec.rb +17 -0
  54. data/spec/octospy/parser/issue_spec.rb +33 -0
  55. data/spec/octospy/parser/organization_spec.rb +33 -0
  56. data/spec/octospy/parser/pull_request_spec.rb +33 -0
  57. data/spec/octospy/parser/repository_spec.rb +101 -0
  58. data/spec/octospy/parser/user_spec.rb +44 -0
  59. data/spec/octospy/parser/wiki_spec.rb +17 -0
  60. data/spec/octospy/parser_spec.rb +63 -0
  61. data/spec/octospy/shortener_spec.rb +46 -0
  62. data/spec/support/shared_context.rb +60 -0
  63. metadata +345 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 47c3a44346c54c0c69fb51561b692fb4f9216304
4
+ data.tar.gz: 80c043163646771135069da36e087dc01cab75c7
5
+ SHA512:
6
+ metadata.gz: d19a444802e932594a9513605314cd665bc85274f12d9a22a5892d9902cb327ee8279979e28f0ef79f3bd468b3b7818069438bea923c20bac07533da16a6ef0d
7
+ data.tar.gz: 25694444c3dd360c39f1fa2549ca27795da1aaff97704b556502b04c2c4784f4bcf3fe4820cd962441a1f01dc150628086fde0f7996b8986bcb1d19d5d7b9ff5
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ vendor
19
+ spec/cassettes
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,23 @@
1
+ language: ruby
2
+
3
+ rvm:
4
+ - 1.9.3
5
+ - 2.0.0
6
+
7
+ before_install:
8
+ - gem update bundler
9
+
10
+ script:
11
+ - bundle exec rake spec
12
+
13
+ notifications:
14
+ email:
15
+ recipients:
16
+ - linyows@gmail.com
17
+ on_success: change
18
+ on_failure: always
19
+ irc:
20
+ on_success: change
21
+ on_failure: always
22
+ channels:
23
+ - "irc.freenode.org#linyows"
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in octospy.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 linyows
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,58 @@
1
+ Octospy
2
+ =======
3
+
4
+ [![Gem Version](https://badge.fury.io/rb/octospy.png)][gem]
5
+ [![Build Status](https://secure.travis-ci.org/linyows/octospy.png?branch=master)][travis]
6
+ [![Dependency Status](https://gemnasium.com/linyows/octospy.png?travis)][gemnasium]
7
+ [![Code Climate](https://codeclimate.com/github/linyows/octospy.png)][codeclimate]
8
+ [![Coverage Status](https://coveralls.io/repos/linyows/octospy/badge.png?branch=master)][coveralls]
9
+
10
+ [gem]: https://rubygems.org/gems/octospy
11
+ [travis]: http://travis-ci.org/linyows/octospy
12
+ [gemnasium]: https://gemnasium.com/linyows/octospy
13
+ [codeclimate]: https://codeclimate.com/github/linyows/octospy
14
+ [coveralls]: https://coveralls.io/r/linyows/octospy
15
+
16
+ Octospy notifies the repository activity to an IRC channel.
17
+
18
+ <img src="http://octodex.github.com/images/daftpunktocat-thomas.gif" width="300">
19
+ <img src="http://octodex.github.com/images/daftpunktocat-guy.gif" width="300">
20
+
21
+ Installation
22
+ ------------
23
+
24
+ Add this line to your application's Gemfile:
25
+
26
+ gem 'octospy'
27
+
28
+ And then execute:
29
+
30
+ $ bundle
31
+
32
+ Or install it yourself as:
33
+
34
+ $ gem install octospy
35
+
36
+ Usage
37
+ -----
38
+
39
+ TODO: Write usage instructions here
40
+
41
+ Contributing
42
+ ------------
43
+
44
+ 1. Fork it
45
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
46
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
47
+ 4. Push to the branch (`git push origin my-new-feature`)
48
+ 5. Create new Pull Request
49
+
50
+ Author
51
+ ------
52
+
53
+ - [linyows](https://github.com/linyows)
54
+
55
+ License
56
+ -------
57
+
58
+ MIT
data/Rakefile ADDED
@@ -0,0 +1,4 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
data/bin/octospy ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ lib = File.expand_path('../../lib', __FILE__)
4
+ require "#{lib}/octospy"
5
+
6
+ Octospy.run
@@ -0,0 +1,91 @@
1
+ module Cinch
2
+ module Plugins
3
+ class Management
4
+ include Cinch::Plugin
5
+
6
+ match(/plugin load (\S+)(?: (\S+))?/, method: :load_plugin)
7
+ match(/plugin unload (\S+)/, method: :unload_plugin)
8
+ match(/plugin reload (\S+)(?: (\S+))?/, method: :reload_plugin)
9
+ match(/plugin set (\S+) (\S+) (.+)$/, method: :set_option)
10
+ def load_plugin(m, plugin, mapping)
11
+ mapping ||= plugin.gsub(/(.)([A-Z])/) { |_|
12
+ $1 + "_" + $2
13
+ }.downcase # we downcase here to also catch the first letter
14
+
15
+ file_name = "lib/cinch/plugins/#{mapping}.rb"
16
+ unless File.exist?(file_name)
17
+ m.reply "Could not load #{plugin} because #{file_name} does not exist."
18
+ return
19
+ end
20
+
21
+ begin
22
+ load(file_name)
23
+ rescue
24
+ m.reply "Could not load #{plugin}."
25
+ raise
26
+ end
27
+
28
+ begin
29
+ const = Cinch::Plugins.const_get(plugin)
30
+ rescue NameError
31
+ m.reply "Could not load #{plugin} because no matching class was found."
32
+ return
33
+ end
34
+
35
+ @bot.plugins.register_plugin(const)
36
+ m.reply "Successfully loaded #{plugin}"
37
+ end
38
+
39
+ def unload_plugin(m, plugin)
40
+ begin
41
+ plugin_class = Cinch::Plugins.const_get(plugin)
42
+ rescue NameError
43
+ m.reply "Could not unload #{plugin} because no matching class was found."
44
+ return
45
+ end
46
+
47
+ @bot.plugins.select {|p| p.class == plugin_class}.each do |p|
48
+ @bot.plugins.unregister_plugin(p)
49
+ end
50
+
51
+ ## FIXME not doing this at the moment because it'll break
52
+ ## plugin options. This means, however, that reloading a
53
+ ## plugin is relatively dirty: old methods will not be removed
54
+ ## but only overwritten by new ones. You will also not be able
55
+ ## to change a classes superclass this way.
56
+ # Cinch::Plugins.__send__(:remove_const, plugin)
57
+
58
+ # Because we're not completely removing the plugin class,
59
+ # reset everything to the starting values.
60
+ plugin_class.hooks.clear
61
+ plugin_class.matchers.clear
62
+ plugin_class.listeners.clear
63
+ plugin_class.timers.clear
64
+ plugin_class.ctcps.clear
65
+ plugin_class.react_on = :message
66
+ plugin_class.plugin_name = nil
67
+ plugin_class.help = nil
68
+ plugin_class.prefix = nil
69
+ plugin_class.suffix = nil
70
+ plugin_class.required_options.clear
71
+
72
+ m.reply "Successfully unloaded #{plugin}"
73
+ end
74
+
75
+ def reload_plugin(m, plugin, mapping)
76
+ unload_plugin(m, plugin)
77
+ load_plugin(m, plugin, mapping)
78
+ end
79
+
80
+ def set_option(m, plugin, option, value)
81
+ begin
82
+ const = Cinch::Plugins.const_get(plugin)
83
+ rescue NameError
84
+ m.reply "Could not set plugin option for #{plugin} because no matching class was found."
85
+ return
86
+ end
87
+ @bot.config.plugins.options[const][option.to_sym] = eval(value)
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,97 @@
1
+ require 'octospy'
2
+
3
+ module Cinch
4
+ module Plugins
5
+ class Octospy
6
+ module Job
7
+ def self.included(base)
8
+ base.class_eval do
9
+ match('job start', method: :start_with_message)
10
+ match('job stop', method: :stop_with_message)
11
+ match('job restart', method: :restart_with_message)
12
+ end
13
+
14
+ Channel.class_eval do
15
+ attr_accessor :job_thread, :last_github_event_id
16
+
17
+ define_method(:job_thread_alive?) do
18
+ @job_thread && @job_thread.alive?
19
+ end
20
+ end
21
+ end
22
+
23
+ def start_with_message(m)
24
+ if m.channel.job_thread_alive?
25
+ m.reply 'I have already started'
26
+ return
27
+ end
28
+
29
+ start(m)
30
+ m.reply 'I started'
31
+ end
32
+
33
+ def stop_with_message(m)
34
+ unless m.channel.job_thread_alive?
35
+ m.reply 'I have not started'
36
+ return
37
+ end
38
+
39
+ stop(m)
40
+ m.reply 'I stopped'
41
+ end
42
+
43
+ def restart_with_message(m)
44
+ if restart(m)
45
+ m.reply 'I restarted'
46
+ else
47
+ m.reply 'I have not started'
48
+ end
49
+ end
50
+
51
+ def start(m)
52
+ repos = ::Octospy.channel(m.channel.name).repos
53
+ channel = m.channel
54
+
55
+ worker = ::Octospy.worker(repos) do |message|
56
+ case message.class.name
57
+ when 'String'
58
+ message.each_char.each_slice(512) do |string|
59
+ channel.notice string.join
60
+ sleep 1
61
+ end
62
+ when 'Array'
63
+ message.each do |line|
64
+ # maximum line length 512
65
+ # http://www.mirc.com/rfc2812.html
66
+ line.each_char.each_slice(512) do |string|
67
+ channel.notice string.join
68
+ sleep 1
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ m.channel.job_thread = worker.thread
75
+ end
76
+
77
+ def stop(m)
78
+ m.channel.job_thread.kill
79
+ end
80
+
81
+ def restart(m)
82
+ if m.channel.job_thread_alive?
83
+ restart!(m)
84
+ true
85
+ else
86
+ false
87
+ end
88
+ end
89
+
90
+ def restart!(m)
91
+ stop(m) if m.channel.job_thread_alive?
92
+ start(m)
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,101 @@
1
+ module Cinch
2
+ module Plugins
3
+ class Octospy
4
+ module Recording
5
+ def self.included(base)
6
+ base.class_eval do
7
+ match(/watch ([\w\-\.]+)\/([\w\-\.]+)/, method: :watch_repository)
8
+ match(/unwatch ([\w\-\.]+)\/([\w\-\.]+)/, method: :unwatch_repository)
9
+ match(/watch ([\w\-\.]+)/, method: :watch_repositories)
10
+ match(/unwatch ([\w\-\.]+)/, method: :unwatch_repositories)
11
+ match(/show watched( repos(itories)?)?/, method: :show_watched_repositories)
12
+ end
13
+ end
14
+
15
+ def watch_repository(m, owner, project)
16
+ repo = "#{owner}/#{project}"
17
+
18
+ unless ::Octokit.repository?(repo)
19
+ m.reply "Sorry, '#{repo}' not found"
20
+ return
21
+ end
22
+
23
+ ::Octospy.add_channel m.channel.name
24
+ ::Octospy.channel(m.channel.name).add_repo(repo)
25
+
26
+ restart(m)
27
+ m.reply "I started to watch the #{repo} events"
28
+ end
29
+
30
+ def watch_repositories(m, owner)
31
+ user = ::Octokit.user?(owner)
32
+
33
+ unless user
34
+ m.reply "Sorry, '#{owner}' not found"
35
+ return
36
+ end
37
+
38
+ ::Octospy.add_channel m.channel.name
39
+ method = "#{'org_' if user.type == 'Organization'}repos".to_sym
40
+ repos = ::Octokit.send(method, owner).map { |repo|
41
+ ::Octospy.channel(m.channel.name).add_repo(repo.full_name)
42
+ repo.full_name
43
+ }
44
+
45
+ if repos.count > 0
46
+ m.reply "I started to watch events of #{repos.count} repositories"
47
+ restart(m)
48
+ end
49
+ end
50
+
51
+ def unwatch_repository(m, owner, project)
52
+ repo = "#{owner}/#{project}"
53
+
54
+ unless ::Octokit.repository?(repo)
55
+ m.reply "Sorry, '#{repo}' not found"
56
+ return
57
+ end
58
+
59
+ ::Octospy.channel(m.channel.name).remove_repo(repo)
60
+
61
+ restart(m)
62
+ m.reply "I stopped to watch the #{repo} events"
63
+ end
64
+
65
+ def unwatch_repositories(m, owner)
66
+ repos = ::Octospy.channel(m.channel.name).repos.each_with_object([]) do |repo, obj|
67
+ next unless repo.split('/').first == owner
68
+ ::Octospy.channel(m.channel.name).remove_repo(repo)
69
+ opj << repo
70
+ end
71
+
72
+ if repos.count > 0
73
+ if ::Octospy.channel(m.channel.name).repos.count > 0
74
+ m.reply "stopped to watch events of #{repos.count} repositories"
75
+ restart(m)
76
+ else
77
+ m.reply "stopped job so no watched repository"
78
+ stop(m)
79
+ end
80
+ end
81
+ end
82
+
83
+ def unwatch_all(m)
84
+ end
85
+
86
+ def show_watched_repositories(m)
87
+ channel = ::Octospy.channel(m.channel.name)
88
+
89
+ if channel.nil? || channel.repos.nil? || !channel.repos
90
+ m.reply 'nothing!'
91
+ return
92
+ end
93
+
94
+ channel.repos.each.with_index(1) do |repo, i|
95
+ m.reply "#{i} #{repo}"
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,68 @@
1
+ require 'cinch/plugins/octospy/recording'
2
+ require 'cinch/plugins/octospy/job'
3
+
4
+ module Cinch
5
+ module Plugins
6
+ class Octospy
7
+ include Cinch::Plugin
8
+ include Octospy::Recording
9
+ include Octospy::Job
10
+
11
+ set :prefix, ->(m) { %r(^#{Regexp.escape "#{m.bot.nick}: "}) }
12
+
13
+ match(/hello|hi|hey/, method: :greet)
14
+ match('ping', method: :pong)
15
+ match('rename', method: :rename)
16
+ match(/join (.+)/, method: :join)
17
+ match(/part(?: (.+))?/, method: :part)
18
+ match(/show status/, method: :show_status)
19
+ match(/show commands/, method: :show_commands)
20
+
21
+ listen_to :invite, method: :join_on_invite
22
+
23
+ def greet(m)
24
+ m.reply "hi #{m.user.nick}"
25
+ end
26
+
27
+ def pong(m)
28
+ m.reply "#{m.user.nick}: pong"
29
+ end
30
+
31
+ def rename(m)
32
+ @bot.nick += '_'
33
+ end
34
+
35
+ def join(m, channel)
36
+ ch = "##{channel.gsub('#', '')}"
37
+ Channel(ch).join
38
+ m.reply "#{ch} joined!"
39
+ end
40
+
41
+ def part(m, channel)
42
+ channel ||= m.channel
43
+ if channel
44
+ ch = "##{channel.gsub('#', '')}"
45
+ Channel(ch).part
46
+ m.reply "#{ch} parted!" unless ch == m.channel
47
+ end
48
+ end
49
+
50
+ def show_status(m)
51
+ @bot.channels.each.with_index(1) do |channel, i|
52
+ number = ::Octospy.channel(channel).repos.count
53
+ m.reply "#{"%02d" % i} #{channel}: #{number} repo"
54
+ end
55
+ end
56
+
57
+ def show_commands(m)
58
+ # @matchers.each.with_index(1) do |matcher, i|
59
+ # m.reply "#{"%02d" % i} #{matcher}"
60
+ # end
61
+ end
62
+
63
+ def join_on_invite(m)
64
+ Channel(m.channel).join
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,49 @@
1
+ module Octospy
2
+ module Configurable
3
+ OPTIONS_KEYS = %i(
4
+ channels
5
+ server
6
+ nick
7
+ github_api_endpoint
8
+ github_web_endpoint
9
+ github_login
10
+ github_token
11
+ ).freeze
12
+
13
+ attr_accessor(*OPTIONS_KEYS)
14
+
15
+ class << self
16
+ def keys
17
+ @keys ||= OPTIONS_KEYS
18
+ end
19
+ end
20
+
21
+ DEFAULT_GITHUB_API_ENDPOINT = ENV['GITHUB_API_ENDPOINT'] || 'https://api.github.com'
22
+ DEFAULT_GITHUB_WEB_ENDPOINT = ENV['GITHUB_WEB_ENDPOINT'] || 'https://github.com'
23
+ DEFAULT_NICK = ENV['NICK'] || 'octospy'
24
+
25
+ def configure
26
+ yield self
27
+ end
28
+
29
+ def options
30
+ Hash[Octospy::Configurable.keys.map{ |key|
31
+ [key, instance_variable_get(:"@#{key}")]
32
+ }]
33
+ end
34
+
35
+ def setup
36
+ @github_api_endpoint = DEFAULT_GITHUB_API_ENDPOINT
37
+ @github_web_endpoint = DEFAULT_GITHUB_WEB_ENDPOINT
38
+ @nick = DEFAULT_NICK
39
+ @channels = if ENV['CHANNELS']
40
+ ENV['CHANNELS'].gsub(/\s|#/, '').split(',').map { |ch| "##{ch}" }
41
+ else
42
+ ''
43
+ end
44
+ @server = ENV['SERVER']
45
+ @github_login = ENV['GITHUB_LOGIN']
46
+ @github_token = ENV['GITHUB_TOKEN']
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,39 @@
1
+ require 'string-irc'
2
+ require 'octospy/shortener'
3
+
4
+ module Octospy
5
+ module Extensions
6
+ module String
7
+ def underscore
8
+ self.gsub('::', '/').
9
+ gsub(/([A-Z\d]+)([A-Z][a-z])/,'\1_\2').
10
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
11
+ tr("-", "_").
12
+ downcase
13
+ end
14
+
15
+ def split_by_linefeed_except_blankline
16
+ self.split(/\r\n|\n/).map { |v| v unless v.eql? '' }.compact
17
+ end
18
+ alias_method :split_lfbl, :split_by_linefeed_except_blankline
19
+
20
+ def colorize_for_irc
21
+ StringIrc.new(self)
22
+ end
23
+
24
+ def shorten_url
25
+ case
26
+ when self =~ /https?:\/\/(\w+\.)?github\.com/
27
+ Octospy::Shortener.shorten_by_github self
28
+ when self =~ /https?:\/\/.+/
29
+ Octospy::Shortener.shorten_by_google self
30
+ else
31
+ self
32
+ end
33
+ end
34
+ alias_method :shorten, :shorten_url
35
+ end
36
+ end
37
+ end
38
+
39
+ ::String.__send__ :include, Octospy::Extensions::String
@@ -0,0 +1,9 @@
1
+ module Octokit
2
+ class Client
3
+ def user?(user, options = {})
4
+ user(user)
5
+ rescue Octokit::NotFound
6
+ false
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,13 @@
1
+ module Octospy
2
+ class Parser
3
+ module Download
4
+ def parse_download_event
5
+ {
6
+ status: "download #{@event.payload.name}",
7
+ title: @event.payload.description,
8
+ link: @event.payload.html_url
9
+ }
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,20 @@
1
+ module Octospy
2
+ class Parser
3
+ module Gist
4
+ def parse_gist_event
5
+ unless @event.payload.gist.description.eql? ''
6
+ title = @event.payload.gist.description
7
+ else
8
+ title = ''
9
+ end
10
+
11
+ {
12
+ status: "#{@event.payload.action}d gist",
13
+ title: title,
14
+ link: @event.payload.gist.html_url,
15
+ none_repository: true
16
+ }
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,43 @@
1
+ module Octospy
2
+ class Parser
3
+ module Issue
4
+ def parse_issues_event
5
+ body = "#{@event.payload.issue.body}".split_lfbl
6
+
7
+ if @event.payload.issue.assignee
8
+ body << "assignee: #{@event.payload.issue.assignee.login}"
9
+ end
10
+
11
+ if @event.payload.issue.milestone
12
+ milestone_title = @event.payload.issue.milestone.title
13
+ milestone_state = @event.payload.issue.milestone.state
14
+ body << "milestone: #{milestone_title}[#{milestone_state}]"
15
+ end
16
+
17
+ {
18
+ status: "#{@event.payload.action} issue ##{@event.payload.issue.number}",
19
+ title: @event.payload.issue.title,
20
+ body: body,
21
+ link: @event.payload.issue.html_url
22
+ }
23
+ end
24
+
25
+ def parse_issue_comment_event
26
+ if @event.payload.action == 'created'
27
+ status = "commented on issue ##{@event.payload.issue.number}"
28
+ title = @event.payload.issue.title
29
+ else
30
+ status = "#{@event.payload.action} issue comment"
31
+ title = ''
32
+ end
33
+
34
+ {
35
+ status: status,
36
+ title: title,
37
+ body: "#{@event.payload.comment.body}".split_lfbl,
38
+ link: @event.payload.comment.html_url
39
+ }
40
+ end
41
+ end
42
+ end
43
+ end