lolcommits 0.5.1 → 0.5.2.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.
@@ -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