lolcommits 0.9.2 → 0.9.3.pre1

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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +6 -0
  3. data/CHANGELOG.md +243 -105
  4. data/CONTRIBUTING.md +2 -2
  5. data/README.md +10 -3
  6. data/bin/lolcommits +9 -16
  7. data/features/step_definitions/lolcommits_steps.rb +0 -1
  8. data/features/support/env.rb +0 -1
  9. data/features/support/path_helpers.rb +0 -1
  10. data/lib/core_ext/mini_magick/utilities.rb +0 -1
  11. data/lib/lolcommits.rb +16 -16
  12. data/lib/lolcommits/backends/git_info.rb +0 -1
  13. data/lib/lolcommits/backends/installation_git.rb +0 -1
  14. data/lib/lolcommits/backends/installation_mercurial.rb +0 -1
  15. data/lib/lolcommits/backends/mercurial_info.rb +0 -1
  16. data/lib/lolcommits/capturer.rb +0 -1
  17. data/lib/lolcommits/capturer/capture_cygwin.rb +0 -1
  18. data/lib/lolcommits/capturer/capture_fake.rb +0 -1
  19. data/lib/lolcommits/capturer/capture_linux.rb +0 -1
  20. data/lib/lolcommits/capturer/capture_linux_animated.rb +0 -1
  21. data/lib/lolcommits/capturer/capture_mac.rb +0 -1
  22. data/lib/lolcommits/capturer/capture_mac_animated.rb +0 -1
  23. data/lib/lolcommits/capturer/capture_windows.rb +0 -1
  24. data/lib/lolcommits/cli/fatals.rb +0 -8
  25. data/lib/lolcommits/cli/launcher.rb +0 -1
  26. data/lib/lolcommits/cli/process_runner.rb +0 -2
  27. data/lib/lolcommits/cli/timelapse_gif.rb +0 -1
  28. data/lib/lolcommits/configuration.rb +10 -7
  29. data/lib/lolcommits/gem_plugin.rb +46 -0
  30. data/lib/lolcommits/installation.rb +0 -1
  31. data/lib/lolcommits/platform.rb +0 -1
  32. data/lib/lolcommits/plugin/base.rb +110 -0
  33. data/lib/lolcommits/plugin/dot_com.rb +50 -0
  34. data/lib/lolcommits/plugin/lol_flowdock.rb +69 -0
  35. data/lib/lolcommits/plugin/lol_hipchat.rb +124 -0
  36. data/lib/lolcommits/plugin/lol_protonet.rb +68 -0
  37. data/lib/lolcommits/plugin/lol_slack.rb +68 -0
  38. data/lib/lolcommits/plugin/lol_tumblr.rb +129 -0
  39. data/lib/lolcommits/plugin/lol_twitter.rb +176 -0
  40. data/lib/lolcommits/plugin/lol_yammer.rb +84 -0
  41. data/lib/lolcommits/plugin/lolsrv.rb +58 -0
  42. data/lib/lolcommits/plugin/loltext.rb +190 -0
  43. data/lib/lolcommits/plugin/term_output.rb +55 -0
  44. data/lib/lolcommits/{plugins → plugin}/tranzlate.rb +14 -15
  45. data/lib/lolcommits/plugin/uploldz.rb +65 -0
  46. data/lib/lolcommits/plugin_manager.rb +48 -0
  47. data/lib/lolcommits/runner.rb +4 -5
  48. data/lib/lolcommits/test_helpers/fake_io.rb +20 -0
  49. data/lib/lolcommits/test_helpers/git_repo.rb +44 -0
  50. data/lib/lolcommits/vcs_info.rb +0 -1
  51. data/lib/lolcommits/version.rb +2 -2
  52. data/lolcommits.gemspec +2 -2
  53. data/test/lolcommits_test.rb +1 -2
  54. data/test/plugins_test.rb +7 -8
  55. metadata +22 -19
  56. data/lib/core_ext/class.rb +0 -8
  57. data/lib/lolcommits/plugin.rb +0 -123
  58. data/lib/lolcommits/plugins/dot_com.rb +0 -51
  59. data/lib/lolcommits/plugins/lol_flowdock.rb +0 -70
  60. data/lib/lolcommits/plugins/lol_hipchat.rb +0 -125
  61. data/lib/lolcommits/plugins/lol_protonet.rb +0 -69
  62. data/lib/lolcommits/plugins/lol_slack.rb +0 -69
  63. data/lib/lolcommits/plugins/lol_tumblr.rb +0 -129
  64. data/lib/lolcommits/plugins/lol_twitter.rb +0 -176
  65. data/lib/lolcommits/plugins/lol_yammer.rb +0 -85
  66. data/lib/lolcommits/plugins/lolsrv.rb +0 -58
  67. data/lib/lolcommits/plugins/loltext.rb +0 -184
  68. data/lib/lolcommits/plugins/term_output.rb +0 -54
  69. data/lib/lolcommits/plugins/uploldz.rb +0 -66
@@ -0,0 +1,50 @@
1
+ require 'httmultiparty'
2
+
3
+ module Lolcommits
4
+ module Plugin
5
+ class DotCom < Base
6
+ BASE_URL = 'http://lolcommits-dot-com.herokuapp.com'.freeze
7
+
8
+ def initialize(runner)
9
+ super
10
+ options.concat(%w(api_key api_secret repo_id))
11
+ end
12
+
13
+ def run_postcapture
14
+ t = Time.now.to_i.to_s
15
+ HTTMultiParty.post(
16
+ "#{BASE_URL}/git_commits.json",
17
+ body: {
18
+ git_commit: {
19
+ sha: runner.sha,
20
+ repo_external_id: configuration['repo_id'],
21
+ image: File.open(runner.main_image),
22
+ raw: File.open(runner.snapshot_loc)
23
+ },
24
+
25
+ key: configuration['api_key'],
26
+ t: t,
27
+ token: Digest::SHA1.hexdigest(configuration['api_secret'] + t)
28
+ }
29
+ )
30
+ rescue => e
31
+ log_error(e, "ERROR: HTTMultiParty POST FAILED #{e.class} - #{e.message}")
32
+ end
33
+
34
+ def configured?
35
+ !configuration['enabled'].nil? &&
36
+ configuration['api_key'] &&
37
+ configuration['api_secret'] &&
38
+ configuration['repo_id']
39
+ end
40
+
41
+ def self.name
42
+ 'dot_com'
43
+ end
44
+
45
+ def self.runner_order
46
+ :postcapture
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,69 @@
1
+ require 'rest_client'
2
+
3
+ module Lolcommits
4
+ module Plugin
5
+ class LolFlowdock < Base
6
+ ENDPOINT_URL = 'api.flowdock.com/flows/'.freeze
7
+ RETRY_COUNT = 2
8
+
9
+ def self.name
10
+ 'flowdock'
11
+ end
12
+
13
+ def self.runner_order
14
+ :postcapture
15
+ end
16
+
17
+ def configured?
18
+ !configuration['access_token'].nil?
19
+ end
20
+
21
+ def configure
22
+ print "Open the URL below and issue a token for your user (Personal API token):\n"
23
+ print "https://flowdock.com/account/tokens\n"
24
+ print "Enter the generated token below, then press enter: \n"
25
+ code = gets.to_s.strip
26
+ print "Enter the machine name of the flow you want to post to from this repo.\n"
27
+ print "Go to https://www.flowdock.com/account and click Flows, then click the flow, then get the machine name from the URL:\n"
28
+ flow = gets.to_s.strip.downcase
29
+ print "Enter the name of the organization for this Flowdock account.\n"
30
+ organization = gets.to_s.strip.downcase
31
+
32
+ {
33
+ 'access_token' => code,
34
+ 'flow' => flow,
35
+ 'organization' => organization
36
+ }
37
+ end
38
+
39
+ def configure_options!
40
+ options = super
41
+ if options['enabled']
42
+ config = configure
43
+ options.merge!(config)
44
+ end
45
+ options
46
+ end
47
+
48
+ def run_postcapture
49
+ retries = RETRY_COUNT
50
+ begin
51
+
52
+ endpoint = 'https://' + configuration['access_token'] + '@' + ENDPOINT_URL + configuration['organization'] + '/' + configuration['flow'] + '/messages'
53
+ response = RestClient.post(
54
+ endpoint,
55
+ event: 'file',
56
+ content: File.new(runner.main_image)
57
+ )
58
+ debug response
59
+ rescue => e
60
+ retries -= 1
61
+ retry if retries > 0
62
+ puts "Posting to flowdock failed - #{e.message}"
63
+ puts 'Try running config again:'
64
+ puts "\tlolcommits --config --plugin flowdock"
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,124 @@
1
+ module Lolcommits
2
+ module Plugin
3
+ class LolHipchat < Base
4
+ def configure_options!
5
+ options = super
6
+ options.merge! configure_auth_options if options['enabled']
7
+ options
8
+ end
9
+
10
+ def configure_auth_options
11
+ puts '-' * 50
12
+ puts ' Lolcommits HipChat Plugin Configuration'
13
+ puts '-' * 50
14
+
15
+ puts '1.) I need your Team Name '
16
+ puts 'teamname as in teamname.hipchat.com, without .hipchat.com'
17
+ print 'Your Teamname: '
18
+ teamname = gets.to_s.strip
19
+ puts "2.) We need a Authentication Token, get yours at https://#{teamname}.hipchat.com/account/api"
20
+ puts 'make sure to select scope "Send Message"'
21
+ print 'Your auth_token: '
22
+ token = gets.to_s.strip
23
+ puts '3.) Which Room should be we post to?'
24
+ puts 'can be a id or name'
25
+ print 'Your Room: '
26
+ room = gets.to_s.strip
27
+
28
+ {
29
+ 'api_token' => token,
30
+ 'api_team' => teamname,
31
+ 'api_room' => room
32
+ }
33
+ end
34
+
35
+ def run_postcapture
36
+ http = Net::HTTP.new(api_url.host, api_url.port)
37
+ # http.set_debug_output $stderr # nice for debugging, never ever release with it
38
+ http.start do |connection|
39
+ header = { 'Content-Type' => 'multipart/related; boundary=0123456789ABLEWASIEREISAWELBA9876543210' }
40
+ data = [message_part, picture_part].map do |part|
41
+ "--0123456789ABLEWASIEREISAWELBA9876543210\r\n#{part}"
42
+ end.join('') << '--0123456789ABLEWASIEREISAWELBA9876543210--'
43
+ connection.post("#{api_url.path}?#{api_url.query}", data, header)
44
+ end
45
+ end
46
+
47
+ def message_part
48
+ [
49
+ 'Content-Type: application/json; charset=UTF-8',
50
+ 'Content-Disposition: attachment; name="metadata"',
51
+ '',
52
+ message_json,
53
+ ''
54
+ ].join "\r\n"
55
+ end
56
+
57
+ def message_json
58
+ { message: message }.to_json.force_encoding('utf-8')
59
+ end
60
+
61
+ def picture_part
62
+ mime_type = MIME::Types.type_for(picture.path)[0] || MIME::Types['application/octet-stream'][0]
63
+ [
64
+ format('Content-Type: %s', mime_type.simplified),
65
+ format('Content-Disposition: attachment; name="file"; filename="%s"', picture.path),
66
+ '',
67
+ "#{picture.read} ",
68
+ ''
69
+ ].join "\r\n"
70
+ end
71
+
72
+ def picture
73
+ @picture ||= File.new(runner.main_image)
74
+ end
75
+
76
+ def api_url
77
+ URI(format('http://%{api_team}.hipchat.com/v2/room/%{api_room}/share/file?auth_token=%{api_token}', symbolized_configuration))
78
+ end
79
+
80
+ def symbolized_configuration
81
+ @symbolized_configuration ||= configuration.each_with_object({}) { |(k, v), obj| obj[k.to_sym] = v }
82
+ end
83
+
84
+ def message
85
+ "commited some #{random_adjective} #{random_object} to #{runner.vcs_info.repo}@#{runner.sha} (#{runner.vcs_info.branch}) "
86
+ end
87
+
88
+ def random_object
89
+ objects = %w(screws bolts exceptions errors cookies)
90
+
91
+ objects.sample
92
+ end
93
+
94
+ def random_adjective
95
+ adjectives = %w(adaptable adventurous affable affectionate agreeable ambitious amiable amicable amusing brave \
96
+ bright broad-minded calm careful charming communicative compassionate conscientious considerate \
97
+ convivial courageous courteous creative decisive determined diligent diplomatic discreet dynamic \
98
+ easygoing emotional energetic enthusiastic exuberant fair-minded faithful fearless forceful \
99
+ frank friendly funny generous gentle good gregarious hard-working helpful honest humorous \
100
+ imaginative impartial independent intellectual intelligent intuitive inventive kind loving loyal \
101
+ modest neat nice optimistic passionate patient persistent pioneering philosophical placid plucky \
102
+ polite powerful practical pro-active quick-witted quiet rational reliable reserved resourceful \
103
+ romantic self-confident self-disciplined sensible sensitive shy sincere sociable straightforward \
104
+ sympathetic thoughtful tidy tough unassuming understanding versatile warmhearted willing witty)
105
+ adjectives.sample
106
+ end
107
+
108
+ def configured?
109
+ super &&
110
+ configuration['api_token'] &&
111
+ configuration['api_team'] &&
112
+ configuration['api_room']
113
+ end
114
+
115
+ def self.name
116
+ 'hipchat'
117
+ end
118
+
119
+ def self.runner_order
120
+ :postcapture
121
+ end
122
+ end
123
+ end
124
+ end
@@ -0,0 +1,68 @@
1
+ require 'rest_client'
2
+
3
+ module Lolcommits
4
+ module Plugin
5
+ class LolProtonet < Base
6
+ def initialize(runner)
7
+ super
8
+ options.concat(%w(api_token api_endpoint))
9
+ end
10
+
11
+ def run_postcapture
12
+ debug "Posting capture to #{configuration['endpoint']}"
13
+ RestClient.post(
14
+ api_url,
15
+ {
16
+ files: [File.new(runner.main_image)],
17
+ message: message
18
+ },
19
+ 'X-Protonet-Token' => configuration['api_token']
20
+ )
21
+ end
22
+
23
+ def api_url
24
+ configuration['api_endpoint']
25
+ end
26
+
27
+ def message
28
+ "commited some #{random_adjective} #{random_object} to #{runner.vcs_info.repo}@#{runner.sha} (#{runner.vcs_info.branch}) "
29
+ end
30
+
31
+ def random_object
32
+ objects = %w(screws bolts exceptions errors cookies)
33
+
34
+ objects.sample
35
+ end
36
+
37
+ def random_adjective
38
+ adjectives = [
39
+ 'awesome', 'great', 'interesting', 'cool', 'EPIC', 'gut', 'good', 'pansy',
40
+ 'powerful', 'boring', 'quirky', 'untested', 'german', 'iranian', 'neutral', 'crazy', 'well tested',
41
+ 'jimmy style', 'nasty', 'bibliographical (we received complaints about the original wording)',
42
+ 'bombdiggidy', 'narly', 'spiffy', 'smashing', 'xing style',
43
+ 'leo apotheker style', 'black', 'white', 'yellow', 'shaggy', 'tasty', 'mind bending', 'JAY-Z',
44
+ 'Kanye (the best ever)', '* Toby Keith was here *', 'splendid', 'stupendulous',
45
+ '(freedom fries!)', '[vote RON PAUL]', '- these are not my glasses -', 'typical pansy',
46
+ '- ze goggles zey do nothing! -', 'almost working', 'legen- wait for it -', '-dairy!',
47
+ ' - Tavonius would be proud of this - ', 'Meg FAILMAN!', '- very brofessional of you -',
48
+ 'heartbleeding', 'juciy', 'supercalifragilisticexpialidocious', 'failing', 'loving'
49
+ ]
50
+ adjectives.sample
51
+ end
52
+
53
+ def configured?
54
+ !configuration['enabled'].nil? &&
55
+ configuration['api_token'] &&
56
+ configuration['api_endpoint']
57
+ end
58
+
59
+ def self.name
60
+ 'lolprotonet'
61
+ end
62
+
63
+ def self.runner_order
64
+ :postcapture
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,68 @@
1
+ require 'rest_client'
2
+
3
+ module Lolcommits
4
+ module Plugin
5
+ class LolSlack < Base
6
+ ENDPOINT_URL = 'https://slack.com/api/files.upload'.freeze
7
+ RETRY_COUNT = 2
8
+
9
+ def self.name
10
+ 'slack'
11
+ end
12
+
13
+ def self.runner_order
14
+ :postcapture
15
+ end
16
+
17
+ def configured?
18
+ !configuration['access_token'].nil?
19
+ end
20
+
21
+ def configure
22
+ print "Open the URL below and issue a token for your user:\n"
23
+ print "https://api.slack.com/web\n"
24
+ print "Enter the generated token below, then press enter: (e.g. xxxx-xxxxxxxxx-xxxx) \n"
25
+ code = gets.to_s.strip
26
+ print "Enter a comma-seperated list of channel IDs to post images in, then press enter: (e.g. C1234567890,C1234567890)\n"
27
+ print "NOTE: you must use channel IDs (not channel names). Grab them from here; https://api.slack.com/methods/channels.list/test\n"
28
+ channels = gets.to_s.strip
29
+
30
+ { 'access_token' => code,
31
+ 'channels' => channels }
32
+ end
33
+
34
+ def configure_options!
35
+ options = super
36
+ if options['enabled']
37
+ config = configure
38
+ options.merge!(config)
39
+ end
40
+ options
41
+ end
42
+
43
+ def run_postcapture
44
+ retries = RETRY_COUNT
45
+ begin
46
+
47
+ response = RestClient.post(
48
+ ENDPOINT_URL,
49
+ file: File.new(runner.main_image),
50
+ token: configuration['access_token'],
51
+ filetype: 'jpg',
52
+ filename: runner.sha,
53
+ title: runner.message + "[#{runner.vcs_info.repo}]",
54
+ channels: configuration['channels']
55
+ )
56
+
57
+ debug response
58
+ rescue => e
59
+ retries -= 1
60
+ retry if retries > 0
61
+ puts "Posting to slack failed - #{e.message}"
62
+ puts 'Try running config again:'
63
+ puts "\tlolcommits --config --plugin slack"
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,129 @@
1
+ require 'yaml'
2
+ require 'oauth'
3
+ require 'webrick'
4
+ require 'cgi'
5
+ require 'tumblr_client'
6
+
7
+ module Lolcommits
8
+ module Plugin
9
+ class LolTumblr < Base
10
+ TUMBLR_API_ENDPOINT = 'https://www.tumblr.com'.freeze
11
+ TUMBLR_CONSUMER_KEY = '2FtMEDpEPkxjoUdkpHh42h9wqTu9IVS7Ra0QyNZGixdCvhllN2'.freeze
12
+ TUMBLR_CONSUMER_SECRET = 'qWuvxgFUR2YyWKtbWOkDTMAiBEbj7ZGaNLaNQPba0PI1N4JpBs'.freeze
13
+
14
+ def run_postcapture
15
+ puts 'Posting to Tumblr'
16
+ r = client.photo(configuration['tumblr_name'], data: runner.main_image)
17
+ if r.key?('id')
18
+ puts "\t--> Post successful!"
19
+ else
20
+ puts "Tumblr post FAILED! #{r}"
21
+ end
22
+ rescue Faraday::Error => e
23
+ puts "Tumblr post FAILED! #{e.message}"
24
+ end
25
+
26
+ def configure_options!
27
+ options = super
28
+ # ask user to configure tokens if enabling
29
+ if options['enabled']
30
+ auth_config = configure_auth!
31
+ return unless auth_config
32
+ options = options.merge(auth_config).merge(configure_tumblr_name)
33
+ end
34
+ options
35
+ end
36
+
37
+ def configure_auth!
38
+ puts '---------------------------'
39
+ puts 'Need to grab tumblr tokens'
40
+ puts '---------------------------'
41
+
42
+ request_token = oauth_consumer.get_request_token(exclude_callback: true)
43
+ print "\n1) Please open this url in your browser to authorize lolcommits:\n\n"
44
+ puts request_token.authorize_url
45
+ print "\n2) Launching a local server to complete the OAuth authentication process:\n\n"
46
+ begin
47
+ server = WEBrick::HTTPServer.new Port: 3000
48
+ server.mount_proc '/', server_callback(server)
49
+ server.start
50
+ debug "Requesting Tumblr OAuth Token with verifier: #{@verifier}"
51
+ access_token = request_token.get_access_token(oauth_verifier: @verifier)
52
+ rescue Errno::EADDRINUSE
53
+ puts "\nERROR You have something running on port 3000. Please turn it off to complete the authorization process"
54
+ return
55
+ rescue OAuth::Unauthorized
56
+ puts "\nERROR: Tumblr OAuth verification faile!"
57
+ return
58
+ end
59
+ return unless access_token.token && access_token.secret
60
+ puts ''
61
+ puts '------------------------------'
62
+ puts 'Thanks! Tumblr Auth Succeeded'
63
+ puts '------------------------------'
64
+
65
+ {
66
+ 'access_token' => access_token.token,
67
+ 'secret' => access_token.secret
68
+ }
69
+ end
70
+
71
+ def configure_tumblr_name
72
+ print "\n3) What's your tumblr name? (i.e. 'http://[THIS PART HERE].tumblr.com'): "
73
+ { 'tumblr_name' => gets.strip }
74
+ end
75
+
76
+ def configured?
77
+ !configuration['enabled'].nil? &&
78
+ configuration['access_token'] &&
79
+ configuration['secret']
80
+ end
81
+
82
+ def client
83
+ @client ||= Tumblr.new(
84
+ consumer_key: TUMBLR_CONSUMER_KEY,
85
+ consumer_secret: TUMBLR_CONSUMER_SECRET,
86
+ oauth_token: configuration['access_token'],
87
+ oauth_token_secret: configuration['secret']
88
+ )
89
+ end
90
+
91
+ def oauth_consumer
92
+ @oauth_consumer ||= OAuth::Consumer.new(
93
+ TUMBLR_CONSUMER_KEY,
94
+ TUMBLR_CONSUMER_SECRET,
95
+ site: TUMBLR_API_ENDPOINT,
96
+ request_endpoint: TUMBLR_API_ENDPOINT,
97
+ http_method: :get
98
+ )
99
+ end
100
+
101
+ def config_with_default(key, default = nil)
102
+ if configuration[key]
103
+ configuration[key].strip.empty? ? default : configuration[key]
104
+ else
105
+ default
106
+ end
107
+ end
108
+
109
+ def self.name
110
+ 'tumblr'
111
+ end
112
+
113
+ def self.runner_order
114
+ :postcapture
115
+ end
116
+
117
+ protected
118
+
119
+ def server_callback(server)
120
+ proc do |req, res|
121
+ q = CGI.parse req.request_uri.query
122
+ @verifier = q['oauth_verifier'][0]
123
+ server.stop
124
+ res.body = 'Lolcommits authorization complete!'
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end