lib/chatterbot/config.rb in chatterbot-1.0.2 vs lib/chatterbot/config.rb in chatterbot-2.0.0.pre
- old
+ new
@@ -1,198 +1,145 @@
module Chatterbot
-
+
#
# routines for storing config information for the bot
module Config
attr_accessor :config
- MAX_TWEET_ID = 9223372036854775807
- COMMAND_LINE_VARIABLES = [:debug_mode, :no_update, :verbose, :reset_since_id]
-
#
# the entire config for the bot, loaded from YAML files and the DB if applicable
def config
@config ||= load_config
end
- #
- # has the config been loaded yet?
- def has_config?
- ! @config.nil?
- end
+ class << self
+ #
+ # simple boolean attribute generator. define the attribute and a
+ # default value and you get a setter and predicate method
+ #
+ # @param [Symbol] key the key for the variable
+ # @param [Boolean] default default value
+ def attr_boolean(key, default=false)
+ class_eval <<-EVAL
+ attr_writer :#{key.to_s}
- #
- # should we log tweets to the database?
- def log_tweets?
- config.has_key?(:db_uri)
- end
+ def #{key.to_s}?
+ (@#{key.to_s} == true) || #{default}
+ end
+ EVAL
+ end
- #
- # Check to see if Sequel was loaded successfully. If not, we won't make any DB calls
- def has_sequel?
- ! defined?(Sequel).nil?
+ #
+ # generate a set of methods to manage checks around the
+ # assortment of since_id values we use to track most recent data
+ # retrieve from twitter
+ #
+ # @param [Symbol] key the key for the variable
+ def attr_since_id(key = nil)
+ attr_name = key.nil? ? "since_id" : ["since_id", key.to_s].join("_")
+ class_eval <<-EVAL
+ def #{attr_name}=(x)
+ config[:#{attr_name}] = x
+ end
+ def #{attr_name}
+ config[:#{attr_name}] || 1
+ end
+
+ def update_#{attr_name}(input)
+ max = max_id_from(input)
+ config[:#{attr_name}] = [config[:#{attr_name}].to_i, max.to_i].max
+ end
+ EVAL
+ end
end
+
+ attr_boolean :debug_mode, false
+ attr_boolean :verbose, false
+ attr_boolean :streaming, false
+ attr_boolean :skip_run, false
+ attr_boolean :only_interact_with_followers, false
+
+ attr_since_id
+ attr_since_id :home_timeline
+ attr_since_id :reply
+ attr_since_id :dm
+
#
- # do we have a DB connection string?
- def has_db?
- has_sequel? && config.has_key?(:db_uri)
+ # should we update our config values?
+ # @param [Boolean] val true/false
+ def no_update=(val)
+ config.no_update = val
end
- def debug_mode=(d)
- config[:debug_mode] = d
+ # should we update our config values?
+ def no_update?
+ config.no_update || false
end
-
- def no_update=(d)
- config[:no_update] = d
+
+ #
+ # return a hash of the params we need to connect to the Twitter API
+ def client_params
+ {
+ :consumer_key => config[:consumer_key],
+ :consumer_secret => config[:consumer_secret],
+ :access_token => config[:access_token],
+ :access_token_secret => config[:access_token_secret]
+ }
end
#
- # should we reset the since_id for this bot?
- #
- def reset_bot?
- config[:reset_since_id] || false
+ # do we have an API key specified?
+ def needs_api_key?
+ config[:consumer_key].nil? || config[:consumer_secret].nil?
end
-
+
#
- # are we in debug mode?
- def debug_mode?
- config[:debug_mode] || false
+ # has this script validated with Twitter OAuth?
+ def needs_auth_token?
+ config[:access_token].nil?
end
+
#
# Should we run any config updates?
def update_config?
- config.has_key?(:no_update) ? ! config[:no_update] : true
+ !no_update?
end
#
# should we write to a log file?
def logging?
- has_config? && config.has_key?(:log_dest)
+ config[:log_dest] != nil
end
-
- def verbose=(v)
- config[:verbose] = v
- end
- def verbose?
- config[:verbose] || false
- end
-
#
# destination for log entries
def log_dest
config[:log_dest]
end
#
- # store since_id to a different key so that it doesn't actually
- # get updated until the bot is done running
- def since_id=(x)
- config[:tmp_since_id] = x
- end
-
+ # given an array or object, return the highest id we can find
+ # @param [Enumerable] s the array to check
#
- # return the ID of the most recent tweet pulled up in searches
- def since_id
- config[:since_id] || 1
- end
-
- #
- # store since_id_reply to a different key so that it doesn't actually
- # get updated until the bot is done running
- def since_id_reply=(x)
- config[:tmp_since_id_reply] = x
- end
-
- #
- # return the ID of the most recent tweet pulled up in mentions or since_id if since_id_reply is nil
- def since_id_reply
- config[:since_id_reply] || since_id
- end
-
- #
- # write out our config file
- def update_config
- return if ! update_config?
-
- # don't update flat file if we can store to the DB instead
- if has_db?
- debug "storing config to database -- you don't need local file anymore"
- store_database_config
- else
- store_local_config
- end
- end
-
- def update_config_at_exit
- update_config
- end
-
def max_id_from(s)
- # don't use max_id if it's this ridiculous number
- # @see https://dev.twitter.com/issues/1300
- sorted = s.reject { |t| !t || t.id == MAX_TWEET_ID }.max { |a, b| a.id <=> b.id }
- sorted && sorted.id
- end
-
- #
- # update the since_id_reply with the id of the given tweet,
- # unless it is lower thant what we have already
- #
- def update_since_id_reply(tweet)
- return if tweet.nil? or tweet.class != Twitter::Tweet || tweet.id == MAX_TWEET_ID
-
- tmp_id = tweet.id
-
- config[:tmp_since_id_reply] = [config[:tmp_since_id_reply].to_i, tmp_id].max
- end
-
- #
- # update the since_id with either the highest ID of the specified
- # tweets, unless it is lower than what we have already
- def update_since_id(search)
- return if search.nil?
+ if ! s.respond_to?(:max)
+ if s.respond_to?(:id)
+ return s.id
+ else
+ return s
+ end
+ end
- tmp_id = if search.is_a?(Twitter::SearchResults)
- search.attrs[:search_metadata][:max_id]
- elsif search.respond_to?(:max)
- max_id_from(search)
- elsif search.is_a?(Twitter::Tweet)
- search.id
- else
- search
- end.to_i
- config[:tmp_since_id] = [config[:tmp_since_id].to_i, tmp_id].max
+ sorted = s.max { |a, b| a.id.to_i <=> b.id.to_i }
+ sorted && sorted.id
end
- #
- # return a hash of the params we need to connect to the Twitter API
- def client_params
- {
- :consumer_key => config[:consumer_key],
- :consumer_secret => config[:consumer_secret],
- :token => config[:token].nil? ? nil : config[:token],
- :secret => config[:secret].nil? ? nil : config[:secret]
- }
- end
#
- # do we have an API key specified?
- def needs_api_key?
- config[:consumer_key].nil? || config[:consumer_secret].nil?
- end
-
- #
- # has this script validated with Twitter OAuth?
- def needs_auth_token?
- config[:token].nil?
- end
-
- #
# determine if we're being called by one of our internal scripts
#
def chatterbot_helper?
Chatterbot::from_helper == true
end
@@ -261,89 +208,19 @@
# bot-specific config settings
def bot_config
{
:consumer_key => ENV["chatterbot_consumer_key"],
:consumer_secret => ENV["chatterbot_consumer_secret"],
- :token => ENV["chatterbot_token"],
- :secret => ENV["chatterbot_secret"]
+ :access_token => ENV["chatterbot_access_token"],
+ :access_token_secret => ENV["chatterbot_access_secret"]
}.delete_if { |k, v| v.nil? }.merge(slurp_file(config_file) || {})
end
-
- #
- # load the config settings from the db, if possible
- def db_config
- return {} if db.nil?
- db[:config][:id => botname]
- end
- #
- # figure out what we should save to the local config file. we don't
- # save anything that exists in the global config, unless it's been modified
- # for this particular bot.
- def config_to_save
- # remove keys that are duped in the global config
- tmp = config.delete_if { |k, v| global_config.has_key?(k) && global_config[k] == config[k] }
-
- # let's not store these, they're just command-line options
- COMMAND_LINE_VARIABLES.each { |k|
- tmp.delete(k)
- }
-
- # update the since_id now
- tmp[:since_id] = tmp.delete(:tmp_since_id) unless ! tmp.has_key?(:tmp_since_id)
- tmp[:since_id_reply] = tmp.delete(:tmp_since_id_reply) unless ! tmp.has_key?(:tmp_since_id_reply)
-
- tmp
- end
#
# load in the config from the assortment of places it can be specified.
def load_config(params={})
- # load the flat-files first
- @config = global_config.merge(bot_config)
- @config[:db_uri] ||= ENV["chatterbot_db"] unless ENV["chatterbot_db"].nil?
-
- # if we have a key to load from the DB, do that now
- if @config.has_key?(:db_uri) && @config[:db_uri]
- tmp = db_config
- @config = @config.merge(tmp) unless tmp.nil?
- end
- @config.merge(params)
+ read_only_data = global_config.merge(bot_config).merge(params)
+ @config = Chatterbot::ConfigManager.new(config_file, read_only_data)
end
-
- #
- # write out the config file for this bot
- def store_local_config
- File.open(config_file, 'w') { |f| YAML.dump(config_to_save, f) }
- end
-
- #
- # store config settings in the database, if possible
- def store_database_config
- return false if db.nil?
-
- configs = db[:config]
- data = {
- :since_id => config.has_key?(:tmp_since_id) ? config[:tmp_since_id] : config[:since_id],
- :since_id_reply => config.has_key?(:tmp_since_id_reply) ? config[:tmp_since_id_reply] : config[:since_id_reply],
- :token => config[:token],
- :secret => config[:secret],
- :consumer_secret => config[:consumer_secret],
- :consumer_key => config[:consumer_key],
- :updated_at => Time.now #:NOW.sql_function
- }
-
- row = configs.filter('id = ?', botname)
-
- if row.count > 0
- row.update(data)
- else
- data[:id] = botname
- data[:created_at] = Time.now #:NOW.sql_function
- configs.insert data
- end
-
- true
- end
-
end
end