Class: FuzzyURL

Inherits:
Object
  • Object
show all
Includes:
Matching, URLComponents
Defined in:
lib/fuzzy_url.rb,
lib/fuzzy_url/version.rb,
lib/fuzzy_url/matching.rb,
lib/fuzzy_url/url_components.rb

Defined Under Namespace

Modules: Matching, URLComponents

Constant Summary collapse

VERSION =
'0.2.1'
VERSION_DATE =
'2014-04-03'

Constants included from URLComponents

URLComponents::COMPONENTS

Class Method Summary collapse

Instance Method Summary collapse

Methods included from URLComponents

#[], #[]=, #fragment, #fragment=, #hostname, #hostname=, #password, #password=, #path, #path=, #port, #port=, #protocol, #protocol=, #query, #query=, #username, #username=

Methods included from Matching

included

Constructor Details

#initialize(url = '') ⇒ FuzzyURL

Creates a new FuzzyURL with the given URL or URL-like object of type String, Hash, or FuzzyURL. Acceptable hash keys are :protocol, :username, :password, :hostname, :port, :path, :query, and :fragment. Hash keys other than these are ignored.



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/fuzzy_url.rb', line 50

def initialize(url='')
  default_components = {:protocol=>nil, :username=>nil, :password=>nil,
                        :hostname=>nil, :port=>nil, :path=>nil,
                        :query=>nil, :fragment=>nil}
  case url
  when String
    unless hash = self.class.url_to_hash(url)
      raise ArgumentError, "Bad url URL: #{url.inspect}"
    end
    @components = default_components.merge(hash)
  when Hash, FuzzyURL
    @components = default_components.merge(url.to_hash)
  else
    raise ArgumentError, "url must be a String, Hash, or FuzzyURL; got #{url.inspect}"
  end
end

Class Method Details

.hash_to_url(hash) ⇒ Object

Given a hash containing :protocol, :username, :password, :hostname, :port, :path, :query, and :fragment fields (all String or nil), return a URL string containing these elements.



165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'lib/fuzzy_url.rb', line 165

def hash_to_url(hash)
  url = ''
  url << "#{ hash[:protocol] }://" if hash[:protocol]
  if hash[:username]
    url << "#{hash[:username]}"
    url << ":#{hash[:password]}" if hash[:password]
    url << '@'
  end
  url << "#{hash[:hostname]}" if hash[:hostname]
  url << ":#{hash[:port]}" if hash[:port]

  ## make sure path starts with a / if it's defined
  path = hash[:path]
  path = "/#{path}" if path && path.index('/') != 0
  url << "#{path}"

  url << "?#{hash[:query]}" if hash[:query]
  url << "##{hash[:fragment]}" if hash[:fragment]
  url
end

.match(mask, url) ⇒ Object

Matches a URL mask string with a URL string. Raises ArgumentError when given malformed URLs. Returns nil on negative match, and an integer match score otherwise. This match score is higher for more specific matches.



197
198
199
200
201
202
203
204
205
# File 'lib/fuzzy_url.rb', line 197

def match(mask, url)
  unless mask_hash = url_to_hash(mask)
    raise ArgumentError, "Badly formed URL mask: #{mask.inspect}"
  end
  unless url_hash = url_to_hash(url)
    raise ArgumentError, "Badly formed URL: #{url.inspect}"
  end
  match_hash(mask_hash, url_hash)
end

.matches?(mask, url) ⇒ Boolean

Matches a URL mask string with a URL string. Raises ArgumentError when given malformed URLs. Returns true on positive match, false otherwise.

Returns:

  • (Boolean)


189
190
191
# File 'lib/fuzzy_url.rb', line 189

def matches?(mask, url)
  match(mask, url) ? true : false
end

.url_to_hash(url) ⇒ Object

Given a URL, returns a hash containing :protocol, :username, :password, :hostname, :port, :path, :query, and :fragment fields (all String

or nil).

Accepts ‘*` in place of any of the above fields, or as part of hostname or path. Returns nil if given a malformed URL.

Example:

“‘ FuzzyURL.url_to_hash(’user:[email protected]:8080/some/path/?foo=bar&baz=1#url-fragment’) # => :username=>“user”, :password=>“pass”, :hostname=>“example.com”, :port=>8080, :path=>“/some/path/”, :query=>“foo=bar&baz=1”, :fragment=>“url-fragment” “‘



114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/fuzzy_url.rb', line 114

def url_to_hash(url)
  if m = url.match(%r{
        ^

        (?: (\* | [a-zA-Z]+) ://)?             ## m[1] is protocol

        (?: (\* | [a-zA-Z0-9_]+)                ## m[2] is username
            (?: : (\* | [a-zA-Z0-9_]*))?        ## m[3] is password
            @
        )?

        ([a-zA-Z0-9\.\*\-]+?)?                 ## m[4] is hostname

        (?: : (\* | \d+))?                     ## m[5] is port

        (/ [^\?\#]*)?                          ## m[6] is path
                                               ## captures leading /

        (?: \? ([^\#]*) )?                     ## m[7] is query

        (?: \# (.*) )?                         ## m[8] is fragment

        $
      }x)

    protocol = m[1] ? m[1].downcase : nil
    username = m[2]
    password = m[3]
    hostname = m[4] ? m[4].downcase : nil
    port     = m[5] ? m[5].to_i : nil
    path     = m[6]
    query    = m[7]
    fragment = m[8]

    { :protocol => protocol,
      :username => username,
      :password => password,
      :hostname => hostname,
      :port     => port,
      :path     => path,
      :query    => query,
      :fragment => fragment }

  else ## no match
    nil
  end
end

Instance Method Details

#match(url) ⇒ Object

Matches the given URL string, hash, or FuzzyURL against this FuzzyURL. Returns nil on negative match, and an integer match score otherwise. This match score is higher for more specific matches.



70
71
72
73
74
75
76
77
78
79
# File 'lib/fuzzy_url.rb', line 70

def match(url)
  case url
  when String
    self.class.match_hash(self.to_hash, self.class.url_to_hash(url))
  when Hash, FuzzyURL
    self.class.match_hash(self.to_hash, url.to_hash)
  else
    raise ArgumentError, "url must be a String, Hash, or FuzzyURL; got #{url.inspect}"
  end
end

#matches?(url) ⇒ Boolean

Matches the given URL string, hash, or FuzzyURL against this FuzzyURL. Returns true on positive match, false otherwise.

Returns:

  • (Boolean)


83
84
85
# File 'lib/fuzzy_url.rb', line 83

def matches?(url)
  match(url) ? true : false
end

#to_hashObject

Returns this FuzzyURL’s hash form.



88
89
90
# File 'lib/fuzzy_url.rb', line 88

def to_hash
  Hash[@components]
end

#to_sObject

Returns this FuzzyURL’s string form.



93
94
95
# File 'lib/fuzzy_url.rb', line 93

def to_s
  self.class.hash_to_url(@components)
end