X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=lib%2Frbot%2Fcore%2Futils%2Ffilters.rb;h=d188aa3f881e3e9c37a4f029624a4b06dcf1d1ce;hb=acc946be5b8d9042fb2a9263ba11d5ded2a509bb;hp=fbd20333f1050da0fbd04732a748590c7dd0cb30;hpb=41e46ac67664f3bbec427d4e332a89783073e856;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git diff --git a/lib/rbot/core/utils/filters.rb b/lib/rbot/core/utils/filters.rb index fbd20333..d188aa3f 100644 --- a/lib/rbot/core/utils/filters.rb +++ b/lib/rbot/core/utils/filters.rb @@ -4,8 +4,6 @@ # :title: Stream filters # # Author:: Giuseppe "Oblomov" Bilotta -# Copyright:: (C) 2008 Giuseppe Bilotta -# License:: GPL v2 # # This file collects methods to handle 'stream filters', a generic mechanism # to transform text+attributes into other text+attributes @@ -51,15 +49,31 @@ module ::Irc alias :filter :call end - # This method processes the DataStream _stream_ with the filters _name_. - # _name_ can be either a single Symbol (filter name), or an Array of - # Symbols, in which case the output of each filter will be used as input - # for the next + # call-seq: + # filter(filter1, filter2, ..., filterN, stream) -> stream + # filter(filter1, filter2, ..., filterN, text, hash) -> stream + # filter(filter1, filter2, ..., filterN, hash) -> stream # - def filter(name, stream={}) + # This method processes the DataStream _stream_ with the filters filter1, + # filter2, ..., _filterN_, in sequence (the output of each filter is used + # as input for the next one. + # _stream_ can be provided either as a DataStream or as a String and a Hash + # (see DataStream.new). + # + def filter(*args) @filters ||= {} - names = (Symbol === name ? [name] : name.dup) - ds = (DataStream === stream ? stream : DataStream.new(stream)) + if Hash === args.last + # the stream is a Hash, check if the previous element is not a Symbol + if Symbol === args[-2] + ds = DataStream.new(args.pop) + else + ds = DataStream.new(*args.slice!(-2, 2)) + end + else + # the stream is just whatever else + ds = DataStream.new(args.pop) + end + names = args.dup return ds if names.empty? # check if filters exist missing = names - @filters.keys @@ -68,19 +82,119 @@ module ::Irc fs.inject(ds) { |mid, f| mid = f.call(mid) } end + # This method returns the global filter name for filter _name_ + # in group _group_ + def global_filter_name(name, group=nil) + (group ? "#{group}.#{name}" : name.to_s).intern + end + + # This method checks if the bot has a filter named _name_ (in group + # _group_) + def has_filter?(name, group=nil) + @filters.key?(global_filter_name(name, group)) + end + + # This method checks if the bot has a filter group named _name_ + def has_filter_group?(name) + @filter_group.key?(name) + end + # This method is used to register a new filter - def register_filter(name, &block) + def register_filter(name, group=nil, &block) raise "No block provided" unless block_given? @filters ||= {} - @filters[name.to_sym] = DataFilter.new &block + tlkey = global_filter_name(name, group) + key = name.to_sym + if has_filter?(tlkey) + debug "Overwriting filter #{tlkey}" + end + @filters[tlkey] = DataFilter.new(&block) + if group + gkey = group.to_sym + @filter_group ||= {} + @filter_group[gkey] ||= {} + if @filter_group[gkey].key?(key) + debug "Overwriting filter #{key} in group #{gkey}" + end + @filter_group[gkey][key] = @filters[tlkey] + end + end + + # This method is used to retrieve the filter names (in a given group) + def filter_names(group=nil) + if group + gkey = group.to_sym + return [] unless defined? @filter_group and @filter_group.key?(gkey) + return @filter_group[gkey].keys + else + return [] unless defined? @filters + return @filters.keys + end + end + + # This method is used to retrieve the filter group names + def filter_groups + return [] unless defined? @filter_group + return @filter_group.keys end # This method clears the filter list and installs the identity filter def clear_filters @filters ||= {} @filters.clear + + @filter_group ||= {} + @filter_group.clear + register_filter(:identity) { |stream| stream } end + + module Plugins + class BotModule + # read accessor for the default filter group for this BotModule + def filter_group + @filter_group ||= name + end + + # write accessor for the default filter group for this BotModule + def filter_group=(name) + @filter_group = name + end + + # define a filter defaulting to the default filter group + # for this BotModule + def define_filter(filter, &block) + @bot.register_filter(filter, self.filter_group, &block) + end + + # load filters associated with the BotModule by looking in + # the path(s) specified by the :path option, defaulting to + # * Config::datadir/filters/.rb + # * botclass/filters/.rb + # (note that as we use #dirname() rather than #name(), + # since we're looking for datafiles; this is only relevant + # for the very few plugins whose dirname differs from name) + def load_filters(options={}) + case options[:path] + when nil + us = "#{self.dirname}.rb" + paths = [ + File.join(Config::datadir, 'filters', us), + @bot.path('filters', us) + ] + when Array + paths = options[:path] + else + paths = [options[:path]] + end + + paths.each do |file| + instance_eval(File.read(file), file) if File.exist?(file) + end + end + end + end + end end