Class: Ace::Support::MacClipboard::ContentParser

Inherits:
Object
  • Object
show all
Defined in:
lib/ace/support/mac_clipboard/content_parser.rb

Class Method Summary collapse

Class Method Details

.parse(raw_result) ⇒ Object



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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/ace/support/mac_clipboard/content_parser.rb', line 9

def self.parse(raw_result)
  return {text: nil, attachments: []} unless raw_result[:success]
  return {text: nil, attachments: []} if raw_result[:types].empty?

  pasteboard = raw_result[:raw_pasteboard]
  types = raw_result[:types]

  text_parts = []
  attachments = []
  image_count = 0

  # Classify all types
  classified = types.map { |uti| [uti, ContentType.classify(uti)] }

  # Process by priority
  ContentType::PRIORITY_ORDER.each do |category|
    relevant_utis = classified.select { |_uti, cat| cat == category }.map(&:first)

    case category
    when :files
      # Read file URLs once (works for both public.file-url and NSFilenamesPboardType)
      file_urls = Reader.read_file_urls(pasteboard)
      file_urls.each do |path|
        attachments << {
          type: :file,
          source_path: path,
          filename: File.basename(path)
        }
      end

    when :image
      relevant_utis.each do |uti|
        data = Reader.read_type(pasteboard, uti)
        next unless data && data.bytesize > 0

        image_count += 1
        format = ContentType.image_format_from_uti(uti)
        ext = ContentType::EXTENSIONS[:image][format]

        attachments << {
          type: :image,
          format: format,
          data: data,
          filename: "clipboard-image-#{image_count}#{ext}"
        }
        break # Only take the first image format
      end

    when :rtf
      relevant_utis.each do |uti|
        data = Reader.read_type(pasteboard, uti)
        next unless data && data.bytesize > 0

        attachments << {
          type: :rtf,
          data: data,
          filename: "clipboard-content.rtf"
        }
        break # Only take the first RTF format
      end

    when :html
      relevant_utis.each do |uti|
        data = Reader.read_type(pasteboard, uti)
        next unless data && data.bytesize > 0

        attachments << {
          type: :html,
          data: data,
          filename: "clipboard-content.html"
        }
        break # Only take the first HTML format
      end

    when :text
      relevant_utis.each do |uti|
        text = Reader.read_string(pasteboard, uti)
        next unless text && !text.empty?

        text_parts << text
        break # Only take the first text format
      end
    end
  end

  # Combine all text parts
  combined_text = text_parts.join("\n\n").strip
  combined_text = nil if combined_text.empty?

  {
    text: combined_text,
    attachments: attachments
  }
end

.parse_file_urls(data) ⇒ Object



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/ace/support/mac_clipboard/content_parser.rb', line 112

def self.parse_file_urls(data)
  return [] unless data

  # Parse file URL data
  urls = []
  url_str = data.force_encoding("UTF-8").strip

  # Handle file:// URLs
  url_str = url_str.sub(%r{^file://}, "")

  # URL decode
  url_str = begin
    URI.decode_www_form_component(url_str)
  rescue
    url_str
  end

  urls << url_str if File.exist?(url_str)
  urls
rescue
  []
end

.parse_html(data) ⇒ Object



156
157
158
159
160
161
162
# File 'lib/ace/support/mac_clipboard/content_parser.rb', line 156

def self.parse_html(data)
  return nil unless data && data.bytesize > 0

  data.force_encoding("UTF-8")
rescue
  nil
end

.parse_image(data, uti) ⇒ Object



135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/ace/support/mac_clipboard/content_parser.rb', line 135

def self.parse_image(data, uti)
  return nil unless data && data.bytesize > 0

  format = ContentType.image_format_from_uti(uti)

  {
    format: format,
    data: data
  }
rescue
  nil
end

.parse_rtf(data) ⇒ Object



148
149
150
151
152
153
154
# File 'lib/ace/support/mac_clipboard/content_parser.rb', line 148

def self.parse_rtf(data)
  return nil unless data && data.bytesize > 0

  data
rescue
  nil
end

.parse_text(data) ⇒ Object



104
105
106
107
108
109
110
# File 'lib/ace/support/mac_clipboard/content_parser.rb', line 104

def self.parse_text(data)
  return nil unless data

  data.force_encoding("UTF-8").strip
rescue
  nil
end