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
##