Class: Nanny::Tracker

Inherits:
Object
  • Object
show all
Defined in:
lib/nanny/tracker.rb

Defined Under Namespace

Classes: MagnetNotFound, PageNotAvailable, TorrentNotFound

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url) ⇒ Tracker

Returns a new instance of Tracker.



12
13
14
# File 'lib/nanny/tracker.rb', line 12

def initialize(url)
  @tracker_url = url
end

Instance Attribute Details

#tracker_urlObject (readonly)

Returns the value of attribute tracker_url.



6
7
8
# File 'lib/nanny/tracker.rb', line 6

def tracker_url
  @tracker_url
end

Instance Method Details

#magnet_uri(progress = Progress.new) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
# File 'lib/nanny/tracker.rb', line 16

def magnet_uri(progress = Progress.new)
  link = progress.step do
    tracker_doc.at_css("a[href^='magnet:']")
  end
  link or raise MagnetNotFound
  MagnetURI.new(link['href'])
rescue PageNotAvailable
  raise MagnetNotFound
ensure
  progress.complete!
end


45
46
47
48
49
50
51
# File 'lib/nanny/tracker.rb', line 45

def plausible_torrent_links
  tracker_doc.css("a[href]").select do |link|
    valid_url?(link['href'])
  end.map do |link|
    to_absolute_url(link['href'])
  end.uniq
end

#to_absolute_url(url) ⇒ Object



53
54
55
56
57
58
59
60
# File 'lib/nanny/tracker.rb', line 53

def to_absolute_url(url)
  uri = Addressable::URI.parse(url)
  if uri.absolute?
    url
  else
    Addressable::URI.parse(tracker_url).join(url).to_s
  end
end

#torrent_content_type?(url) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
71
72
73
74
75
76
77
78
# File 'lib/nanny/tracker.rb', line 68

def torrent_content_type?(url)
  thread = Thread.new {
    Thread.current[:headers] = begin
                                 HTTPClient.headers(url)
                               rescue HTTPClient::Exception
                                 nil
                               end
  }.join(2)
  thread && thread[:headers] or raise PageNotAvailable
  thread[:headers][:content_type] =~ /bittorrent|octet/
end

#torrent_url(progress = Progress.new) ⇒ Object



28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'lib/nanny/tracker.rb', line 28

def torrent_url(progress = Progress.new)
  progress.step do
    links = plausible_torrent_links
    progress.todo(links.count)
    links.each do |url|
      is_torrent = torrent_content_type?(url)
      progress.done!(1)
      return url if is_torrent
    end
  end
  raise TorrentNotFound
rescue PageNotAvailable
  raise TorrentNotFound
ensure
  progress.complete!
end

#tracker_docObject



80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/nanny/tracker.rb', line 80

def tracker_doc
  @tracker_doc ||= begin
    thread = Thread.new {
      Thread.current[:data] = begin
                                HTTPClient.get(tracker_url)
                              rescue HTTPClient::Exception
                                nil
                              end
    }.join(2)
    thread && thread[:data] or raise PageNotAvailable
    Nokogiri::HTML(thread[:data])
  end
end

#valid_url?(url) ⇒ Boolean

Returns:

  • (Boolean)


62
63
64
65
66
# File 'lib/nanny/tracker.rb', line 62

def valid_url?(url)
  url =~ /\.torrent$/ && Addressable::URI.parse(url)
rescue Addressable::URI::InvalidURIError
  false
end