lolcommits 0.5.1 → 0.5.2.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,40 +1,83 @@
1
1
  module Lolcommits
2
2
  class Plugin
3
3
  include Methadone::CLILogging
4
- attr_accessor :default, :name, :runner, :options
5
4
 
6
- def configuration
7
- config = runner.config.user_configuration
8
- return Hash.new if config.nil?
9
- config[self.name] || Hash.new
10
- end
5
+ attr_accessor :runner, :options
11
6
 
12
7
  def initialize(runner)
8
+ debug "Initializing"
13
9
  self.runner = runner
14
10
  self.options = ['enabled']
11
+ end
15
12
 
16
- plugdebug "Initializing"
13
+ def execute
14
+ if is_enabled?
15
+ debug "I am enabled, about to run"
16
+ run
17
+ else
18
+ debug "Disabled, doing nothing for execution"
19
+ end
17
20
  end
18
21
 
19
- def is_enabled?
20
- enabled_config = configuration['enabled']
21
- return self.default if enabled_config.nil? || enabled_config == ''
22
- return enabled_config
22
+ def run
23
+ debug "base plugin, does nothing to anything"
23
24
  end
24
25
 
26
+ def configuration
27
+ config = runner.config.read_configuration if runner
28
+ return Hash.new unless config
29
+ config[self.class.name] || Hash.new
30
+ end
25
31
 
26
- def execute
27
- if is_enabled?
28
- plugdebug "I am enabled, about to run"
29
- run
32
+ # ask for plugin options
33
+ def configure_options!
34
+ puts "Configuring plugin: #{self.class.name}\n"
35
+ options.inject(Hash.new) do |acc, option|
36
+ print "#{option}: "
37
+ val = STDIN.gets.strip.downcase
38
+ if %w(true yes).include?(val)
39
+ val = true
40
+ elsif %(false no).include?(val)
41
+ val = false
42
+ end
43
+ acc.merge(option => val)
44
+ end
45
+ end
46
+
47
+ def is_enabled?
48
+ configuration['enabled'] == true
49
+ end
50
+
51
+ # check config is valid
52
+ def valid_configuration?
53
+ if is_configured?
54
+ true
30
55
  else
31
- plugdebug "Disabled, doing nothing for execution"
56
+ puts "Missing #{self.class.name} config - configure with: lolcommits --config -p #{self.class.name}"
57
+ false
32
58
  end
33
59
  end
34
60
 
35
- # uniform debug logging output for plugins
36
- def plugdebug(msg)
37
- debug("Plugin: #{self.class.to_s}: " + msg)
61
+ # empty plugin configuration
62
+ def is_configured?
63
+ !configuration.empty?
64
+ end
65
+
66
+ # uniform puts for plugins
67
+ # dont puts if the runner wants to be silent (stealth mode)
68
+ def puts(*args)
69
+ return if runner && runner.capture_stealth
70
+ super(args)
71
+ end
72
+
73
+ # uniform debug logging for plugins
74
+ def debug(msg)
75
+ super("Plugin: #{self.class.to_s}: " + msg)
76
+ end
77
+
78
+ # identifying plugin name (for config, listing)
79
+ def self.name
80
+ 'plugin'
38
81
  end
39
82
  end
40
83
  end
@@ -2,17 +2,17 @@ require 'httmultiparty'
2
2
 
3
3
  module Lolcommits
4
4
  class DotCom < Plugin
5
+
5
6
  def initialize(runner)
6
7
  super
7
-
8
- self.name = 'dot_com'
9
- self.default = false
10
8
  self.options.concat(['api_key', 'api_secret', 'repo_id'])
11
9
  end
12
10
 
13
11
  def run
12
+ return unless valid_configuration?
13
+
14
14
  t = Time.now.to_i.to_s
15
- resp = HTTMultiParty.post('http://www.lolcommits.com/git_commits.json',
15
+ resp = HTTMultiParty.post('http://www.lolcommits.com/git_commits.json',
16
16
  :body => {
17
17
  :git_commit => {
18
18
  :sha => self.runner.sha,
@@ -28,5 +28,15 @@ module Lolcommits
28
28
  )
29
29
  end
30
30
 
31
+ def is_configured?
32
+ !configuration['enabled'].nil? &&
33
+ configuration['api_key'] &&
34
+ configuration['api_secret'] &&
35
+ configuration['repo_id']
36
+ end
37
+
38
+ def self.name
39
+ 'dot_com'
40
+ end
31
41
  end
32
42
  end
@@ -3,101 +3,123 @@ require 'oauth'
3
3
 
4
4
  # twitter gem currently spams stdout when activated, surpress warnings just during the inital require
5
5
  original_verbose, $VERBOSE = $VERBOSE, nil # Supress warning messages.
6
- require 'twitter'
7
- $VERBOSE = original_verbose # Activate warning messages again.
8
-
9
- TWITTER_CONSUMER_KEY = 'qc096dJJCxIiqDNUqEsqQ'
10
- TWITTER_CONSUMER_SECRET = 'rvjNdtwSr1H0TvBvjpk6c4bvrNydHmmbvv7gXZQI'
6
+ require 'twitter'
7
+ $VERBOSE = original_verbose # activate warning messages again.
11
8
 
12
9
  module Lolcommits
13
-
14
10
  class LolTwitter < Plugin
15
11
 
16
- def initialize(runner)
17
- super
18
- self.name = 'twitter'
19
- self.default = false
12
+ TWITTER_CONSUMER_KEY = 'qc096dJJCxIiqDNUqEsqQ'
13
+ TWITTER_CONSUMER_SECRET = 'rvjNdtwSr1H0TvBvjpk6c4bvrNydHmmbvv7gXZQI'
14
+ TWITTER_RETRIES = 2
15
+ TWITTER_PIN_REGEX = /^\d{4,}$/ # 4 or more digits
16
+
17
+ def run
18
+ return unless valid_configuration?
19
+
20
+ attempts = 0
21
+
22
+ begin
23
+ attempts += 1
24
+ tweet = build_tweet(self.runner.message)
25
+ puts "Tweeting: #{tweet}"
26
+ debug "--> Tweeting! (attempt: #{attempts}, tweet size: #{tweet.length} chars)"
27
+ if client.update_with_media(tweet, File.open(self.runner.main_image, 'r'))
28
+ puts "\t--> Tweet Sent!"
29
+ end
30
+ rescue Twitter::Error::InternalServerError,
31
+ Twitter::Error::BadRequest,
32
+ Twitter::Error::ClientError => e
33
+ debug "Tweet FAILED! #{e.class} - #{e.message}"
34
+ retry if attempts < TWITTER_RETRIES
35
+ puts "ERROR: Tweet FAILED! (after #{attempts} attempts) - #{e.message}"
36
+ end
20
37
  end
21
38
 
22
- def initial_twitter_auth
23
- puts "\n--------------------------------------------"
24
- puts "Need to grab twitter tokens (first time only)"
25
- puts "---------------------------------------------"
39
+ def build_tweet(commit_message, tag = "#lolcommits")
40
+ available_commit_msg_size = max_tweet_size - (tag.length + 1)
41
+ if commit_message.length > available_commit_msg_size
42
+ commit_message = "#{commit_message[0..(available_commit_msg_size-3)]}..."
43
+ end
44
+ "#{commit_message} #{tag}"
45
+ end
26
46
 
27
- consumer = OAuth::Consumer.new(TWITTER_CONSUMER_KEY,
47
+ def configure_options!
48
+ options = super
49
+ # ask user to configure tokens if enabling
50
+ if options['enabled'] == true
51
+ if auth_config = configure_auth!
52
+ options.merge!(auth_config)
53
+ else
54
+ # return nil if configure_auth failed
55
+ return
56
+ end
57
+ end
58
+ return options
59
+ end
60
+
61
+ def configure_auth!
62
+ puts "---------------------------"
63
+ puts "Need to grab twitter tokens"
64
+ puts "---------------------------"
65
+
66
+ consumer = OAuth::Consumer.new(TWITTER_CONSUMER_KEY,
28
67
  TWITTER_CONSUMER_SECRET,
29
68
  :site => 'http://api.twitter.com',
30
69
  :request_endpoint => 'http://api.twitter.com',
31
70
  :sign_in => true)
32
71
 
33
72
  request_token = consumer.get_request_token
34
- rtoken = request_token.token
35
- rsecret = request_token.secret
73
+ rtoken = request_token.token
74
+ rsecret = request_token.secret
36
75
 
37
- puts "\n1.) Open the following url in your browser, get the PIN:\n\n"
76
+ print "\n1) Please open this url in your browser to get a PIN for lolcommits:\n\n"
38
77
  puts request_token.authorize_url
39
- puts "\n2.) Enter PIN, then press enter:"
78
+ print "\n2) Enter PIN, then press enter: "
79
+ twitter_pin = STDIN.gets.strip.downcase.to_s
40
80
 
41
- begin
42
- STDOUT.flush
43
- twitter_pin = STDIN.gets.chomp
44
- rescue
45
- end
46
-
47
- if (twitter_pin.nil?) || (twitter_pin.length == 0)
48
- puts "\n\tERROR: Could not read PIN, auth fail"
81
+ unless twitter_pin =~ TWITTER_PIN_REGEX
82
+ puts "\nERROR: '#{twitter_pin}' is not a valid Twitter Auth PIN"
49
83
  return
50
84
  end
51
85
 
52
86
  begin
87
+ debug "Requesting Twitter OAuth Token with PIN: #{twitter_pin}"
53
88
  OAuth::RequestToken.new(consumer, rtoken, rsecret)
54
89
  access_token = request_token.get_access_token(:oauth_verifier => twitter_pin)
55
- rescue Twitter::Unauthorized
56
- puts "> FAIL!"
90
+ rescue OAuth::Unauthorized
91
+ puts "\nERROR: Twitter PIN Auth FAILED!"
57
92
  return
58
93
  end
59
94
 
60
- # saves the config back to yaml file.
61
- self.runner.config.do_configure!('twitter', { 'enabled' => true,
62
- 'access_token' => access_token.token,
63
- 'secret' => access_token.secret })
64
- end
65
-
66
- def run
67
- commit_msg = self.runner.message
68
- available_commit_msg_size = 128
69
- tweet_msg = commit_msg.length > available_commit_msg_size ? "#{commit_msg[0..(available_commit_msg_size-3)]}..." : commit_msg
70
- tweet_text = "#{tweet_msg} #lolcommits"
71
- puts "Tweeting: #{tweet_text}"
72
-
73
- if configuration['access_token'].nil? || configuration['secret'].nil?
74
- initial_twitter_auth()
75
- end
76
-
77
- if configuration['access_token'].nil? || configuration['secret'].nil?
78
- puts "Missing Twitter Credentials - Skipping The Tweet"
79
- return
95
+ if access_token.token && access_token.secret
96
+ print "\n3) Thanks! Twitter Auth Succeeded\n"
97
+ return { 'access_token' => access_token.token,
98
+ 'secret' => access_token.secret }
80
99
  end
100
+ end
81
101
 
82
- Twitter.configure do |config|
83
- config.consumer_key = TWITTER_CONSUMER_KEY
84
- config.consumer_secret = TWITTER_CONSUMER_SECRET
85
- end
102
+ def is_configured?
103
+ !configuration['enabled'].nil? &&
104
+ configuration['access_token'] &&
105
+ configuration['secret']
106
+ end
86
107
 
87
- client = Twitter::Client.new(
88
- :oauth_token => configuration['access_token'],
108
+ def client
109
+ @client ||= Twitter::Client.new(
110
+ :consumer_key => TWITTER_CONSUMER_KEY,
111
+ :consumer_secret => TWITTER_CONSUMER_SECRET,
112
+ :oauth_token => configuration['access_token'],
89
113
  :oauth_token_secret => configuration['secret']
90
114
  )
91
- retries = 2
92
- begin
93
- if client.update_with_media(tweet_text, File.open(self.runner.main_image, 'r'))
94
- puts "\t--> Tweet Sent!"
95
- end
96
- rescue Twitter::Error::InternalServerError
97
- retries -= 1
98
- retry if retries > 0
99
- puts "\t ! --> Tweet 500 Error - Tweet Not Posted"
100
- end
115
+ end
116
+
117
+ def max_tweet_size
118
+ 139 - client.configuration.characters_reserved_per_media
119
+ end
120
+
121
+ def self.name
122
+ 'twitter'
101
123
  end
102
124
  end
103
125
  end
@@ -4,42 +4,31 @@ require "json"
4
4
  require "logger"
5
5
 
6
6
  module Lolcommits
7
-
8
7
  class Lolsrv < Plugin
9
8
 
10
- SERVER = 'server'
11
-
12
9
  def initialize(runner)
13
10
  super
14
- self.name = 'lolsrv'
15
- self.default = false
16
- self.options << SERVER
17
-
11
+ self.options << 'server'
12
+ if self.runner
13
+ @logger = Logger.new(File.new(self.runner.config.loldir + "/lolsrv.log", "a+"))
14
+ end
18
15
  end
19
16
 
20
17
  def run
21
-
22
- log_file = File.new(self.runner.config.loldir + "/lolsrv.log", "a+")
23
- @logger = Logger.new(log_file)
24
-
25
- if configuration[SERVER].nil?
26
- puts "Missing server configuration. Use lolcommits --config -p lolsrv"
27
- return
28
- end
18
+ return unless valid_configuration?
19
+ fork { sync() }
20
+ end
29
21
 
30
- fork do
31
- sync()
32
- end
22
+ def is_configured?
23
+ !configuration["enabled"].nil? && configuration["server"]
33
24
  end
34
25
 
35
26
  def sync
36
27
  existing = get_existing_lols
37
28
  unless existing.nil?
38
- Dir.glob(self.runner.config.loldir + "/*.jpg") do |item|
39
- next if item == '.' or item == '..'
40
- # do work on real items
41
- sha = File.basename(item, '.*')
42
- unless existing.include?(sha) || sha == 'tmp_snapshot'
29
+ Dir[self.runner.config.loldir + "/*.{jpg,gif}"].each do |item|
30
+ sha = File.basename(item, ".*")
31
+ unless existing.include?(sha) || sha == "tmp_snapshot"
43
32
  upload(item, sha)
44
33
  end
45
34
  end
@@ -49,11 +38,10 @@ module Lolcommits
49
38
  def get_existing_lols
50
39
  begin
51
40
  lols = JSON.parse(
52
- RestClient.get(configuration[SERVER] + '/lols'))
41
+ RestClient.get(configuration['server'] + "/lols"))
53
42
  lols.map { |lol| lol["sha"] }
54
- rescue => error
55
- @logger.info "Existing lols could not be retrieved with Error " + error.message
56
- @logger.info error.backtrace
43
+ rescue => e
44
+ log_error(e, "ERROR: existing lols could not be retrieved #{e.class} - #{e.message}")
57
45
  return nil
58
46
  end
59
47
  end
@@ -61,13 +49,24 @@ module Lolcommits
61
49
  def upload(file, sha)
62
50
  begin
63
51
  RestClient.post(
64
- configuration[SERVER] + '/uplol',
65
- :lol => File.new(file),
66
- :sha => sha)
67
- rescue => error
68
- @logger.info "Upload of LOL "+ sha + " failed with Error " + error.message
52
+ configuration["server"] + "/uplol",
53
+ :lol => File.new(file),
54
+ :sha => sha
55
+ )
56
+ rescue => e
57
+ log_error(e,"ERROR: Upload of lol #{sha} FAILED #{e.class} - #{e.message}")
69
58
  return
70
59
  end
71
60
  end
61
+
62
+ def log_error(e, message)
63
+ debug message
64
+ @logger.info message
65
+ @logger.info e.backtrace
66
+ end
67
+
68
+ def self.name
69
+ "lolsrv"
70
+ end
72
71
  end
73
72
  end
@@ -3,22 +3,21 @@ module Lolcommits
3
3
 
4
4
  def initialize(runner)
5
5
  super
6
-
7
6
  @font_location = runner ? runner.font : nil
8
-
9
- self.name = 'loltext'
10
- self.default = true
11
7
  end
12
8
 
13
- def run
14
- mm_run
9
+ # enabled by default (if no configuration exists)
10
+ def is_enabled?
11
+ !is_configured? || super
15
12
  end
16
13
 
17
- # use minimagick wrapper
18
- def mm_run
19
- font_location = @font_location || File.join(Configuration::LOLCOMMITS_ROOT, "vendor", "fonts", "Impact.ttf")
14
+ def run
15
+ font_location = @font_location || File.join(Configuration::LOLCOMMITS_ROOT,
16
+ "vendor",
17
+ "fonts",
18
+ "Impact.ttf")
20
19
 
21
- plugdebug "Annotating image via MiniMagick"
20
+ debug "Annotating image via MiniMagick"
22
21
  image = MiniMagick::Image.open(self.runner.main_image)
23
22
  image.combine_options do |c|
24
23
  c.gravity 'SouthWest'
@@ -41,34 +40,14 @@ module Lolcommits
41
40
  c.annotate '0', self.runner.sha
42
41
  end
43
42
 
44
- plugdebug "Writing changed file to #{self.runner.main_image}"
43
+ debug "Writing changed file to #{self.runner.main_image}"
45
44
  image.write self.runner.main_image
46
45
  end
47
46
 
48
- # use Rmagick wrapper (deprecated, no longer works in IM6.10+)
49
- # def rm_run
50
- # canvas = ImageList.new(self.runner.main_image)
51
- # draw = Magick::Draw.new
52
- # draw.font = File.join(Configuration::LOLCOMMITS_ROOT, "vendor", "fonts", "Impact.ttf")
53
-
54
- # draw.fill = 'white'
55
- # draw.stroke = 'black'
56
-
57
- # draw.annotate(canvas, 0, 0, 0, 0, self.runner.sha) do
58
- # self.gravity = NorthEastGravity
59
- # self.pointsize = 32
60
- # self.stroke_width = 2
61
- # end
62
-
63
- # draw.annotate(canvas, 0, 0, 0, 0, word_wrap(self.runner.message)) do
64
- # self.gravity = SouthWestGravity
65
- # self.pointsize = 48
66
- # self.interline_spacing = -(48 / 5) if self.respond_to?(:interline_spacing)
67
- # self.stroke_width = 2
68
- # end
47
+ def self.name
48
+ 'loltext'
49
+ end
69
50
 
70
- # canvas.write(runner.main_image)
71
- # end
72
51
 
73
52
  private
74
53