lib/sup/util.rb in sup-0.12.1 vs lib/sup/util.rb in sup-0.13.0

- old
+ new

@@ -3,10 +3,11 @@ require 'mime/types' require 'pathname' require 'set' require 'enumerator' require 'benchmark' +require 'iconv' ## time for some monkeypatching! class Symbol unless method_defined? :to_proc def to_proc @@ -109,10 +110,35 @@ # unless message.header['MIME-Version'] # message.header['MIME-Version'] = "1.0" # end end end + + class Header + ## Be more cautious about invalid content-type headers + ## the original RMail code calls + ## value.strip.split(/\s*;\s*/)[0].downcase + ## without checking if split returned an element + + # This returns the full content type of this message converted to + # lower case. + # + # If there is no content type header, returns the passed block is + # executed and its return value is returned. If no block is passed, + # the value of the +default+ argument is returned. + def content_type(default = nil) + if value = self['content-type'] and ct = value.strip.split(/\s*;\s*/)[0] + return ct.downcase + else + if block_given? + yield + else + default + end + end + end + end end class Range ## only valid for integer ranges (unless I guess it's exclusive) def size @@ -210,11 +236,12 @@ class String ## nasty multibyte hack for ruby 1.8. if it's utf-8, split into chars using ## the utf8 regex and count those. otherwise, use the byte length. def display_length if RUBY_VERSION < '1.9.1' && ($encoding == "UTF-8" || $encoding == "utf8") - scan(/./u).size + # scan hack is somewhat slow, worth trying to cache + @display_length ||= scan(/./u).size else size end end @@ -444,11 +471,11 @@ each_with_index { |x, i| ret << yield(x, i) } ret end def sum; inject(0) { |x, y| x + y }; end - + def map_to_hash ret = {} each { |x| ret[x] = yield(x) } ret end @@ -512,81 +539,10 @@ def last= e; self[-1] = e end def nonempty?; !empty? end end -class Time - def to_indexable_s - sprintf "%012d", self - end - - def nearest_hour - if min < 30 - self - else - self + (60 - min) * 60 - end - end - - def midnight # within a second - self - (hour * 60 * 60) - (min * 60) - sec - end - - def is_the_same_day? other - (midnight - other.midnight).abs < 1 - end - - def is_the_day_before? other - other.midnight - midnight <= 24 * 60 * 60 + 1 - end - - def to_nice_distance_s from=Time.now - later_than = (self < from) - diff = (self.to_i - from.to_i).abs.to_f - text = - [ ["second", 60], - ["minute", 60], - ["hour", 24], - ["day", 7], - ["week", 4.345], # heh heh - ["month", 12], - ["year", nil], - ].argfind do |unit, size| - if diff.round <= 1 - "one #{unit}" - elsif size.nil? || diff.round < size - "#{diff.round} #{unit}s" - else - diff /= size.to_f - false - end - end - if later_than - text + " ago" - else - "in " + text - end - end - - TO_NICE_S_MAX_LEN = 9 # e.g. "Yest.10am" - def to_nice_s from=Time.now - if year != from.year - strftime "%b %Y" - elsif month != from.month - strftime "%b %e" - else - if is_the_same_day? from - strftime("%l:%M%p").downcase # emulate %P (missing on ruby 1.8 darwin) - elsif is_the_day_before? from - "Yest." + nearest_hour.strftime("%l%p").downcase # emulate %P - else - strftime "%b %e" - end - end - end -end - ## simple singleton module. far less complete and insane than the ruby standard ## library one, but it automatically forwards methods calls and allows for ## constructors that take arguments. ## ## classes that inherit this can define initialize. however, you cannot call @@ -604,10 +560,18 @@ ## useful because threads that might be active during the ## cleanup process (e.g. polling) would otherwise have to ## special-case every call to a Singleton object return nil if @instance.nil? + # Speed up further calls by defining a shortcut around method_missing + if meth.to_s[-1,1] == '=' + # Argh! Inconsistency! Setters do not work like all the other methods. + class_eval "def self.#{meth}(a); @instance.send :#{meth}, a; end" + else + class_eval "def self.#{meth}(*a, &b); @instance.send :#{meth}, *a, &b; end" + end + @instance.send meth, *a, &b end def init *args raise "there can be only one! (instance)" if instantiated? @instance = new(*args) @@ -627,10 +591,10 @@ ## ## class C ## attr_accessor :val ## def initialize; @val = 0 end ## end -## +## ## h = Hash.new { C.new } ## h[:a].val # => 0 ## h[:a].val = 1 ## h[:a].val # => 0 ##