searchlink 2.3.85 → 2.3.87

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,178 @@
1
+ # encoding: utf-8
2
+
3
+ # = plist
4
+ #
5
+ # Copyright 2006-2010 Ben Bleything and Patrick May
6
+ # Distributed under the MIT License
7
+ #
8
+
9
+ module Plist
10
+ # === Create a plist
11
+ # You can dump an object to a plist in one of two ways:
12
+ #
13
+ # * <tt>Plist::Emit.dump(obj)</tt>
14
+ # * <tt>obj.to_plist</tt>
15
+ # * This requires that you mixin the <tt>Plist::Emit</tt> module, which is already done for +Array+ and +Hash+.
16
+ #
17
+ # The following Ruby classes are converted into native plist types:
18
+ # Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time, true, false
19
+ # * +Array+ and +Hash+ are both recursive; their elements will be converted into plist nodes inside the <array> and <dict> containers (respectively).
20
+ # * +IO+ (and its descendants) and +StringIO+ objects are read from and their contents placed in a <data> element.
21
+ # * User classes may implement +to_plist_node+ to dictate how they should be serialized; otherwise the object will be passed to <tt>Marshal.dump</tt> and the result placed in a <data> element.
22
+ #
23
+ # For detailed usage instructions, refer to USAGE[link:files/docs/USAGE.html] and the methods documented below.
24
+ module Emit
25
+ DEFAULT_INDENT = "\t"
26
+
27
+ # Helper method for injecting into classes. Calls <tt>Plist::Emit.dump</tt> with +self+.
28
+ def to_plist(envelope = true, options = {})
29
+ Plist::Emit.dump(self, envelope, options)
30
+ end
31
+
32
+ # Helper method for injecting into classes. Calls <tt>Plist::Emit.save_plist</tt> with +self+.
33
+ def save_plist(filename, options = {})
34
+ Plist::Emit.save_plist(self, filename, options)
35
+ end
36
+
37
+ # The following Ruby classes are converted into native plist types:
38
+ # Array, Bignum, Date, DateTime, Fixnum, Float, Hash, Integer, String, Symbol, Time
39
+ #
40
+ # Write us (via RubyForge) if you think another class can be coerced safely into one of the expected plist classes.
41
+ #
42
+ # +IO+ and +StringIO+ objects are encoded and placed in <data> elements; other objects are <tt>Marshal.dump</tt>'ed unless they implement +to_plist_node+.
43
+ #
44
+ # The +envelope+ parameters dictates whether or not the resultant plist fragment is wrapped in the normal XML/plist header and footer. Set it to false if you only want the fragment.
45
+ def self.dump(obj, envelope = true, options = {})
46
+ options = { :indent => DEFAULT_INDENT }.merge(options)
47
+
48
+ output = PlistBuilder.new(options[:indent]).build(obj)
49
+ output = wrap(output) if envelope
50
+
51
+ output
52
+ end
53
+
54
+ # Writes the serialized object's plist to the specified filename.
55
+ def self.save_plist(obj, filename, options = {})
56
+ File.open(filename, 'wb') do |f|
57
+ f.write(obj.to_plist(true, options))
58
+ end
59
+ end
60
+
61
+ private
62
+
63
+ class PlistBuilder
64
+ def initialize(indent_str)
65
+ @indent_str = indent_str.to_s
66
+ end
67
+
68
+ def build(element, level=0)
69
+ if element.respond_to? :to_plist_node
70
+ element.to_plist_node
71
+ else
72
+ case element
73
+ when Array
74
+ if element.empty?
75
+ tag('array', nil, level)
76
+ else
77
+ tag('array', nil, level) {
78
+ element.collect {|e| build(e, level + 1) }.join
79
+ }
80
+ end
81
+ when Hash
82
+ if element.empty?
83
+ tag('dict', nil, level)
84
+ else
85
+ tag('dict', '', level) do
86
+ element.sort_by{|k,v| k.to_s }.collect do |k,v|
87
+ tag('key', CGI.escapeHTML(k.to_s), level + 1) +
88
+ build(v, level + 1)
89
+ end.join
90
+ end
91
+ end
92
+ when true, false
93
+ tag(element, nil, level)
94
+ when Time
95
+ tag('date', element.utc.strftime('%Y-%m-%dT%H:%M:%SZ'), level)
96
+ when Date # also catches DateTime
97
+ tag('date', element.strftime('%Y-%m-%dT%H:%M:%SZ'), level)
98
+ when String, Symbol, Integer, Float
99
+ tag(element_type(element), CGI.escapeHTML(element.to_s), level)
100
+ when IO, StringIO
101
+ data = element.tap(&:rewind).read
102
+ data_tag(data, level)
103
+ else
104
+ data = Marshal.dump(element)
105
+ comment_tag('The <data> element below contains a Ruby object which has been serialized with Marshal.dump.') +
106
+ data_tag(data, level)
107
+ end
108
+ end
109
+ end
110
+
111
+ private
112
+
113
+ def tag(type, contents, level, &block)
114
+ if block_given?
115
+ indent("<#{type}>\n", level) +
116
+ block.call +
117
+ indent("</#{type}>\n", level)
118
+ elsif contents.to_s.empty?
119
+ indent("<#{type}/>\n", level)
120
+ else
121
+ indent("<#{type}>#{contents.to_s}</#{type}>\n", level)
122
+ end
123
+ end
124
+
125
+ def data_tag(data, level)
126
+ # note that apple plists are wrapped at a different length then
127
+ # what ruby's pack wraps by default.
128
+ tag('data', nil, level) do
129
+ [data].pack("m") # equivalent to Base64.encode64(data)
130
+ .gsub(/\s+/, '')
131
+ .scan(/.{1,68}/o)
132
+ .collect { |line| indent(line, level) }
133
+ .join("\n")
134
+ .concat("\n")
135
+ end
136
+ end
137
+
138
+ def indent(str, level)
139
+ @indent_str.to_s * level + str
140
+ end
141
+
142
+ def element_type(item)
143
+ case item
144
+ when String, Symbol
145
+ 'string'
146
+ when Integer
147
+ 'integer'
148
+ when Float
149
+ 'real'
150
+ else
151
+ raise "Don't know about this data type... something must be wrong!"
152
+ end
153
+ end
154
+
155
+ def comment_tag(content)
156
+ return "<!-- #{content} -->\n"
157
+ end
158
+ end
159
+
160
+ def self.wrap(contents)
161
+ output = '<?xml version="1.0" encoding="UTF-8"?>' + "\n"
162
+ output << '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' + "\n"
163
+ output << '<plist version="1.0">' + "\n"
164
+ output << contents
165
+ output << '</plist>' + "\n"
166
+
167
+ output
168
+ end
169
+ end
170
+ end
171
+
172
+ class Array #:nodoc:
173
+ include Plist::Emit
174
+ end
175
+
176
+ class Hash #:nodoc:
177
+ include Plist::Emit
178
+ end
@@ -0,0 +1,263 @@
1
+ # encoding: utf-8
2
+
3
+ # = plist
4
+ #
5
+ # Copyright 2006-2010 Ben Bleything and Patrick May
6
+ # Distributed under the MIT License
7
+ #
8
+
9
+ # Plist parses Mac OS X xml property list files into ruby data structures.
10
+ #
11
+ # === Load a plist file
12
+ # This is the main point of the library:
13
+ #
14
+ # r = Plist.parse_xml(filename_or_xml)
15
+ module Plist
16
+ # Raised when an element is not implemented
17
+ class UnimplementedElementError < RuntimeError; end
18
+
19
+ # Note that I don't use these two elements much:
20
+ #
21
+ # + Date elements are returned as DateTime objects.
22
+ # + Data elements are implemented as Tempfiles
23
+ #
24
+ # Plist.parse_xml will blow up if it encounters a Date element.
25
+ # If you encounter such an error, or if you have a Date element which
26
+ # can't be parsed into a Time object, please create an issue
27
+ # attaching your plist file at https://github.com/patsplat/plist/issues
28
+ # so folks can implement the proper support.
29
+ #
30
+ # By default, <data> will be assumed to be a marshaled Ruby object and
31
+ # interpreted with <tt>Marshal.load</tt>. Pass <tt>marshal: false</tt>
32
+ # to disable this behavior and return the raw binary data as an IO
33
+ # object instead.
34
+ def self.parse_xml(filename_or_xml, options={})
35
+ listener = Listener.new(options)
36
+ # parser = REXML::Parsers::StreamParser.new(File.new(filename), listener)
37
+ parser = StreamParser.new(filename_or_xml, listener)
38
+ parser.parse
39
+ listener.result
40
+ end
41
+
42
+ class Listener
43
+ # include REXML::StreamListener
44
+
45
+ attr_accessor :result, :open
46
+
47
+ def initialize(options={})
48
+ @result = nil
49
+ @open = []
50
+ @options = { :marshal => true }.merge(options).freeze
51
+ end
52
+
53
+ def tag_start(name, attributes)
54
+ @open.push PTag.mappings[name].new(@options)
55
+ end
56
+
57
+ def text(contents)
58
+ if @open.last
59
+ @open.last.text ||= ''.dup
60
+ @open.last.text.concat(contents)
61
+ end
62
+ end
63
+
64
+ def tag_end(name)
65
+ last = @open.pop
66
+ if @open.empty?
67
+ @result = last.to_ruby
68
+ else
69
+ @open.last.children.push last
70
+ end
71
+ end
72
+ end
73
+
74
+ class StreamParser
75
+ def initialize(plist_data_or_file, listener)
76
+ if plist_data_or_file.respond_to? :read
77
+ @xml = plist_data_or_file.read
78
+ elsif File.exist? plist_data_or_file
79
+ @xml = File.read(plist_data_or_file)
80
+ else
81
+ @xml = plist_data_or_file
82
+ end
83
+
84
+ @listener = listener
85
+ end
86
+
87
+ TEXT = /([^<]+)/
88
+ CDATA = /<!\[CDATA\[(.*?)\]\]>/
89
+ XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>*/m
90
+ DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/m
91
+ COMMENT_START = /\A<!--/
92
+ COMMENT_END = /.*?-->/m
93
+ UNIMPLEMENTED_ERROR = 'Unimplemented element. ' \
94
+ 'Consider reporting via https://github.com/patsplat/plist/issues'
95
+
96
+ def parse
97
+ plist_tags = PTag.mappings.keys.join('|')
98
+ start_tag = /<(#{plist_tags})([^>]*)>/i
99
+ end_tag = /<\/(#{plist_tags})[^>]*>/i
100
+
101
+ require 'strscan'
102
+
103
+ @scanner = StringScanner.new(@xml)
104
+ until @scanner.eos?
105
+ if @scanner.scan(COMMENT_START)
106
+ @scanner.scan(COMMENT_END)
107
+ elsif @scanner.scan(XMLDECL_PATTERN)
108
+ encoding = parse_encoding_from_xml_declaration(@scanner[1])
109
+ next if encoding.nil?
110
+
111
+ # use the specified encoding for the rest of the file
112
+ next unless String.method_defined?(:force_encoding)
113
+ @scanner.string = @scanner.rest.force_encoding(encoding)
114
+ elsif @scanner.scan(DOCTYPE_PATTERN)
115
+ next
116
+ elsif @scanner.scan(start_tag)
117
+ @listener.tag_start(@scanner[1], nil)
118
+ if (@scanner[2] =~ /\/$/)
119
+ @listener.tag_end(@scanner[1])
120
+ end
121
+ elsif @scanner.scan(TEXT)
122
+ @listener.text(@scanner[1])
123
+ elsif @scanner.scan(CDATA)
124
+ @listener.text(@scanner[1])
125
+ elsif @scanner.scan(end_tag)
126
+ @listener.tag_end(@scanner[1])
127
+ else
128
+ raise UnimplementedElementError.new(UNIMPLEMENTED_ERROR)
129
+ end
130
+ end
131
+ end
132
+
133
+ private
134
+
135
+ def parse_encoding_from_xml_declaration(xml_declaration)
136
+ return unless defined?(Encoding)
137
+
138
+ xml_encoding = xml_declaration.match(/(?:\A|\s)encoding=(?:"(.*?)"|'(.*?)')(?:\s|\Z)/)
139
+
140
+ return if xml_encoding.nil?
141
+
142
+ begin
143
+ Encoding.find(xml_encoding[1])
144
+ rescue ArgumentError
145
+ nil
146
+ end
147
+ end
148
+ end
149
+
150
+ class PTag
151
+ def self.mappings
152
+ @mappings ||= {}
153
+ end
154
+
155
+ def self.inherited(sub_class)
156
+ key = sub_class.to_s.downcase
157
+ key.gsub!(/^plist::/, '')
158
+ key.gsub!(/^p/, '') unless key == "plist"
159
+
160
+ mappings[key] = sub_class
161
+ end
162
+
163
+ attr_accessor :text, :children, :options
164
+ def initialize(options)
165
+ @children = []
166
+ @options = options
167
+ end
168
+
169
+ def to_ruby
170
+ raise "Unimplemented: " + self.class.to_s + "#to_ruby on #{self.inspect}"
171
+ end
172
+ end
173
+
174
+ class PList < PTag
175
+ def to_ruby
176
+ children.first.to_ruby if children.first
177
+ end
178
+ end
179
+
180
+ class PDict < PTag
181
+ def to_ruby
182
+ dict = {}
183
+ key = nil
184
+
185
+ children.each do |c|
186
+ if key.nil?
187
+ key = c.to_ruby
188
+ else
189
+ dict[key] = c.to_ruby
190
+ key = nil
191
+ end
192
+ end
193
+
194
+ dict
195
+ end
196
+ end
197
+
198
+ class PKey < PTag
199
+ def to_ruby
200
+ CGI.unescapeHTML(text || '')
201
+ end
202
+ end
203
+
204
+ class PString < PTag
205
+ def to_ruby
206
+ CGI.unescapeHTML(text || '')
207
+ end
208
+ end
209
+
210
+ class PArray < PTag
211
+ def to_ruby
212
+ children.collect do |c|
213
+ c.to_ruby
214
+ end
215
+ end
216
+ end
217
+
218
+ class PInteger < PTag
219
+ def to_ruby
220
+ text.to_i
221
+ end
222
+ end
223
+
224
+ class PTrue < PTag
225
+ def to_ruby
226
+ true
227
+ end
228
+ end
229
+
230
+ class PFalse < PTag
231
+ def to_ruby
232
+ false
233
+ end
234
+ end
235
+
236
+ class PReal < PTag
237
+ def to_ruby
238
+ text.to_f
239
+ end
240
+ end
241
+
242
+ require 'date'
243
+ class PDate < PTag
244
+ def to_ruby
245
+ DateTime.parse(text)
246
+ end
247
+ end
248
+
249
+ class PData < PTag
250
+ def to_ruby
251
+ # unpack("m")[0] is equivalent to Base64.decode64
252
+ data = text.gsub(/\s+/, '').unpack("m")[0] unless text.nil?
253
+ begin
254
+ return Marshal.load(data) if options[:marshal]
255
+ rescue Exception
256
+ end
257
+ io = StringIO.new
258
+ io.write data
259
+ io.rewind
260
+ io
261
+ end
262
+ end
263
+ end
@@ -0,0 +1,5 @@
1
+ # encoding: utf-8
2
+
3
+ module Plist
4
+ VERSION = '3.7.2'.freeze
5
+ end
@@ -1,212 +1,22 @@
1
- # frozen_string_literal: true
1
+ # encoding: utf-8
2
2
 
3
3
  # = plist
4
4
  #
5
+ # This is the main file for plist. Everything interesting happens in
6
+ # Plist and Plist::Emit.
7
+ #
5
8
  # Copyright 2006-2010 Ben Bleything and Patrick May
6
9
  # Distributed under the MIT License
7
- module Plist; end
8
-
9
- # === Load a plist file
10
- # This is the main point of the library:
11
10
  #
12
- # r = Plist::parse_xml( filename_or_xml )
13
- module Plist
14
- def self.parse_xml(filename_or_xml)
15
- listener = Listener.new
16
- parser = StreamParser.new(filename_or_xml, listener)
17
- parser.parse
18
- listener.result
19
- end
20
-
21
- class Listener
22
- attr_accessor :result, :open
23
-
24
- def initialize
25
- @result = nil
26
- @open = []
27
- end
28
-
29
- def tag_start(name, _attributes)
30
- @open.push PTag.mappings[name].new
31
- end
32
-
33
- def text(contents)
34
- @open.last.text = contents if @open.last
35
- end
36
-
37
- def tag_end(_name)
38
- last = @open.pop
39
- if @open.empty?
40
- @result = last.to_ruby
41
- else
42
- @open.last.children.push last
43
- end
44
- end
45
- end
46
-
47
- class StreamParser
48
- def initialize(plist_data_or_file, listener)
49
- @xml = if plist_data_or_file.respond_to? :read
50
- plist_data_or_file.read
51
- elsif File.exist? plist_data_or_file
52
- File.read(plist_data_or_file)
53
- else
54
- plist_data_or_file
55
- end
56
-
57
- @listener = listener
58
- end
59
-
60
- TEXT = /([^<]+)/.freeze
61
- XMLDECL_PATTERN = /<\?xml\s+(.*?)\?>*/um.freeze
62
- DOCTYPE_PATTERN = /\s*<!DOCTYPE\s+(.*?)(\[|>)/um.freeze
63
- COMMENT_START = /\A<!--/u.freeze
64
- COMMENT_END = /.*?-->/um.freeze
65
-
66
- def parse
67
- plist_tags = PTag.mappings.keys.join("|")
68
- start_tag = /<(#{plist_tags})([^>]*)>/i
69
- end_tag = %r{</(#{plist_tags})[^>]*>}i
70
-
71
- require "strscan"
72
-
73
- @scanner = StringScanner.new(@xml)
74
- until @scanner.eos?
75
- next unless @scanner.scan(COMMENT_START)
76
-
77
- @scanner.scan(COMMENT_END)
78
- if @scanner.scan(start_tag)
79
- @listener.tag_start(@scanner[1], nil)
80
- @listener.tag_end(@scanner[1]) if @scanner[2] =~ %r{/$}
81
- elsif @scanner.scan(TEXT)
82
- @listener.text(@scanner[1])
83
- elsif @scanner.scan(end_tag)
84
- @listener.tag_end(@scanner[1])
85
- else
86
- raise "Unimplemented element"
87
- end
88
- end
89
- end
90
-
91
- class PTag
92
- @@mappings = {}
93
- def self.mappings
94
- @@mappings
95
- end
96
-
97
- def self.inherited(sub_class)
98
- key = sub_class.to_s.downcase
99
- key.gsub!(/^plist::/, "")
100
- key.gsub!(/^p/, "") unless key == "plist"
101
-
102
- @@mappings[key] = sub_class
103
- super
104
- end
105
-
106
- attr_accessor :text, :children
107
-
108
- def initialize
109
- @children = []
110
- end
111
-
112
- def to_ruby
113
- raise "Unimplemented: #{self.class}#to_ruby on #{inspect}"
114
- end
115
- end
116
-
117
- class PList < PTag
118
- def to_ruby
119
- children.first&.to_ruby
120
- end
121
- end
122
-
123
- class PDict < PTag
124
- def to_ruby
125
- dict = {}
126
- key = nil
127
-
128
- children.each do |c|
129
- if key.nil?
130
- key = c.to_ruby
131
- else
132
- dict[key] = c.to_ruby
133
- key = nil
134
- end
135
- end
136
-
137
- dict
138
- end
139
- end
140
-
141
- class PKey < PTag
142
- def to_ruby
143
- CGI.unescapeHTML(text || "")
144
- end
145
- end
146
-
147
- class PString < PTag
148
- def to_ruby
149
- CGI.unescapeHTML(text || "")
150
- end
151
- end
152
-
153
- class PArray < PTag
154
- def to_ruby
155
- children.collect(&:to_ruby)
156
- end
157
- end
158
-
159
- class PInteger < PTag
160
- def to_ruby
161
- text.to_i
162
- end
163
- end
164
-
165
- class PTrue < PTag
166
- def to_ruby
167
- true
168
- end
169
- end
170
-
171
- class PFalse < PTag
172
- def to_ruby
173
- false
174
- end
175
- end
176
-
177
- class PReal < PTag
178
- def to_ruby
179
- text.to_f
180
- end
181
- end
182
-
183
- require "date"
184
-
185
- class PDate < PTag
186
- def to_ruby
187
- DateTime.parse(text)
188
- end
189
- end
190
11
 
191
- require "base64"
12
+ require "cgi"
13
+ require "stringio"
192
14
 
193
- class PData < PTag
194
- def to_ruby
195
- data = Base64.decode64(text.gsub(/\s+/, ""))
15
+ # import
16
+ require_relative "plist/generator"
196
17
 
197
- begin
198
- Marshal.load(data)
199
- rescue Exception
200
- io = StringIO.new
201
- io.write data
202
- io.rewind
203
- io
204
- end
205
- end
206
- end
207
- end
208
- end
18
+ # import
19
+ require_relative "plist/parser"
209
20
 
210
- # module Plist
211
- # VERSION = '3.1.0'
212
- # end
21
+ # import
22
+ require_relative "plist/version"
@@ -55,9 +55,7 @@ module SL
55
55
  end
56
56
 
57
57
  %w[url title link_text].each do |key|
58
- unless res.key?(key)
59
- raise PluginError.new(%("#{File.basename(@script)}" output missing key "#{key}"), plugin: @filename)
60
- end
58
+ raise PluginError.new(%("#{File.basename(@script)}" output missing key "#{key}"), plugin: @filename) unless res.key?(key)
61
59
  end
62
60
 
63
61
  [res["url"], res["title"], res["link_text"]]
@@ -5,8 +5,6 @@ module SL
5
5
  include URL
6
6
 
7
7
  class SearchLink
8
- include Plist
9
-
10
8
  attr_reader :originput, :output, :clipboard
11
9
 
12
10
  private
@@ -37,9 +35,7 @@ module SL
37
35
  else
38
36
  case search_type
39
37
  when /^r$/ # simple replacement
40
- if SL.config["validate_links"] && !SL::URL.valid_link?(search_terms)
41
- return [false, "Link not valid: #{search_terms}", link_text]
42
- end
38
+ return [false, "Link not valid: #{search_terms}", link_text] if SL.config["validate_links"] && !SL::URL.valid_link?(search_terms)
43
39
 
44
40
  title = SL::URL.title(search_terms) || search_terms
45
41
 
@@ -43,7 +43,9 @@ module SL
43
43
  return false
44
44
  end
45
45
 
46
- url = "https://customsearch.googleapis.com/customsearch/v1?cx=338419ee5ac894523&q=#{ERB::Util.url_encode(search_terms.gsub(/%22/, '"'))}&num=1&key=#{@api_key}"
46
+ url = "https://customsearch.googleapis.com/customsearch/v1?cx=338419ee5ac894523&q=#{ERB::Util.url_encode(search_terms.gsub(
47
+ '%22', '"'
48
+ ))}&num=1&key=#{@api_key}"
47
49
  json = Curl::Json.new(url).json
48
50
 
49
51
  if json["error"] && json["error"]["code"].to_i == 429