Class: Recluse::Link

Inherits:
Object
  • Object
show all
Defined in:
lib/recluse/link.rb

Overview

A simple link container for a profile’s queue.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, parent) ⇒ Link

Create a link.

Raises:



30
31
32
33
34
35
36
37
# File 'lib/recluse/link.rb', line 30

def initialize(url, parent)
  raise LinkError, 'Incorrect parent URL. Expects :root or a string.' unless parent == :root || parent.class == String
  @url = url
  @parent = parent
  @address = @parent == :root ? Addressable::URI.parse(@url) : Addressable::URI.join(@parent, @url)
  @address.fragment = nil
  @absolute = @address.to_s
end

Instance Attribute Details

#absoluteObject (readonly)

The absolute URL of the link.



22
23
24
# File 'lib/recluse/link.rb', line 22

def absolute
  @absolute
end

#addressObject (readonly)

The Addressable::URI representation of the link.



26
27
28
# File 'lib/recluse/link.rb', line 26

def address
  @address
end

#parentObject (readonly)

Parent of link (i.e. the referrer). Can be :root if no parent.



18
19
20
# File 'lib/recluse/link.rb', line 18

def parent
  @parent
end

#urlObject (readonly)

URL of link. Can be relative.



14
15
16
# File 'lib/recluse/link.rb', line 14

def url
  @url
end

Class Method Details

.internal_to?(root, to) ⇒ Boolean

Check if to is internal compared to root. Building block of internal?. Both root and to must be of type Addressable::URI.

A link is internal compared to the root if it matches the following conditions:

  • Same scheme, subdomain, and domain. In other words, a relative URL can be built out of the link.

  • If root is a directory and doesn’t contain a filename (e.g. http://example.com/test/):

    • Internal if link is below the root’s path or is the same (e.g. http://example.com/test/index.php).

  • Otherwise if root contains a filename (e.g. http://example.com/test/index.php):

    • Internal if link is below parent directory of root (e.g. http://example.com/test/about.php).

Returns:

  • (Boolean)


83
84
85
86
87
88
89
90
91
92
93
# File 'lib/recluse/link.rb', line 83

def self.internal_to?(root, to)
  route = root.route_to(to)
  return false if route == to # can't be represented as relative url
  route_internal = route.to_s[0...3] != '../'
  has_slash = root.path[-1] == '/'
  return route_internal if has_slash || !root.extname.empty?
  slashed_root = root.dup
  slashed_root.path = "#{root.path}/"
  slashed_route = slashed_root.route_to(to)
  (slashed_route.to_s[0...3] != '../')
end

Instance Method Details

#inspectObject

Inspection



47
48
49
# File 'lib/recluse/link.rb', line 47

def inspect
  to_s
end

#internal?(addrroots, scheme_squash: false) ⇒ Boolean

Is the link internal compared to Addressable::URI roots?

Returns:

  • (Boolean)


53
54
55
56
57
58
59
# File 'lib/recluse/link.rb', line 53

def internal?(addrroots, scheme_squash: false)
  return true if @parent == :root
  return addrroots.any? { |root| Link.internal_to?(root, @address) } unless scheme_squash
  a2 = @address.dup
  a2.scheme = a2.scheme == 'https' ? 'http' : 'https'
  addrroots.any? { |root| (Link.internal_to?(root, @address) || Link.internal_to?(root, a2)) }
end

#match?(globs) ⇒ Boolean

Does the link match any of the globs?

Returns:

  • (Boolean)


69
70
71
# File 'lib/recluse/link.rb', line 69

def match?(globs)
  [*globs].any? { |glob| File.fnmatch(glob, @absolute) }
end

#run?(blacklist, whitelist) ⇒ Boolean

Is the link runnable compared to the black- and whitelists, and the link scheme?

Returns:

  • (Boolean)


63
64
65
# File 'lib/recluse/link.rb', line 63

def run?(blacklist, whitelist)
  ((@address.scheme == 'http') || (@address.scheme == 'https')) && (!match?(blacklist) || match?(whitelist))
end

#to_sObject

Output as string.



41
42
43
# File 'lib/recluse/link.rb', line 41

def to_s
  @absolute
end