aboutsummaryrefslogtreecommitdiff
blob: a2c725182cbc9fc56023f4a259c06f9886b1bcb4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
require 'charlock_holmes'

module Parallel::ProcessorCount
  module_function :processor_count
end

module Ag
  module Utils
    module_function

    def fix_encoding2(str)
      s = str.encode('UTF-8', 'UTF-8', invalid: :replace, replace: '')
      s = s.unpack('C*').pack('U*') unless s.valid_encoding?
      s
    end

    def fix_encoding(str, fail_hard = false)
      detection = CharlockHolmes::EncodingDetector.detect(str)
      CharlockHolmes::Converter.convert(str, detection[:encoding], 'UTF-8')
    rescue => e
      raise e if fail_hard
      $stderr.puts e.message if $options.debug
      'Encoding could not be reliably detected. Contents not available.'
    end

    def resolve_id
      id = $options.dir
      case $options.argmode
      when :msgid
        id = Ag::Storage.resolve_message_id($options.name, $options.dir)
      when :file
        id = Ag::Storage.resolve_filename($options.name, $options.dir)
      when :hash
        id = Ag::Storage.resolve_hash($options.name, $options.dir)
      when :dir
        abort 'Cannot perform resolve a directory to a message id'
      when nil
        abort 'Cannot resolve a nil id'
      end

      id
    end

    def resolve_address_header(message, header)
      if message[header].is_a? Mail::StructuredField
        # Good header, properly parsed
        message[header].addrs.map { |s| fix_encoding(s.to_s) }
      elsif nil == message[header]
        # Header not set, return empty
        []
      else
        # Parsing failed, do best-effort parsing
        [message[header].to_s.split(/,\s*/)].flatten.map { |s| fix_encoding(s) }
      end
    rescue ArgumentError
      []
    end

    def get_sender_displayname(message)
      begin
        display_name = message[:from].addrs.first.display_name
        display_name ||= message[:from].addrs.first.to_s

        fix_encoding(display_name).strip
      rescue NoMethodError
        fix_encoding(message[:from].to_s).strip
      end
    rescue ArgumentError
      ''
    end

    @proc_count = nil
    def proc_count=(cnt)
      cnt = nil if cnt == false
      @proc_count = cnt
    end

    def proc_count
      return @proc_count unless @proc_count.nil? || @proc_count == false
      (Parallel::ProcessorCount.processor_count.to_f * 0.75).floor
    end
  end
end
# vim: ts=2 sts=2 et ft=ruby: