Class: LeechtopDownloader::Client
- Inherits:
-
Object
- Object
- LeechtopDownloader::Client
- Extended by:
- T::Sig
- Defined in:
- lib/leechtop_downloader/client.rb
Overview
Client handles the network requests to Leechtop.
Defined Under Namespace
Classes: DownloadError
Class Method Summary collapse
- .download(url) ⇒ Object
- .download_from_html(html) ⇒ Object
- .extract_direct_url(url) ⇒ Object
- .extract_page_links(url) ⇒ Object
- .fetch_ajax_direct_link(tokens) ⇒ Object
- .fetch_html(url) ⇒ Object
- .fetch_metadata(url) ⇒ Object
- .parse_ajax_response(body) ⇒ Object
- .parse_tokens(html) ⇒ Object
Class Method Details
.download(url) ⇒ Object
23 24 25 26 27 28 29 30 31 32 |
# File 'lib/leechtop_downloader/client.rb', line 23 def self.download(url) direct_url = extract_direct_url(url) Down.download(direct_url, open_timeout: 10, read_timeout: 60) rescue Down::NotFound raise DownloadError, 'The file could not be found on the host server (404 Not Found). It may have been deleted.' rescue Down::ClientError, Down::ServerError => e raise DownloadError, "The host server rejected the download: #{e.}" rescue StandardError => e raise DownloadError, "Network or extraction failure: #{e.}" end |
.download_from_html(html) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/leechtop_downloader/client.rb', line 38 def self.download_from_html(html) tokens = parse_tokens(html) direct_url = fetch_ajax_direct_link(tokens) Down.download(direct_url, open_timeout: 10, read_timeout: 60) rescue Down::NotFound raise DownloadError, 'The file could not be found on the host server (404 Not Found). It may have been deleted.' rescue Down::ClientError, Down::ServerError => e raise DownloadError, "The host server rejected the download: #{e.}" rescue StandardError => e raise DownloadError, "Network or extraction failure: #{e.}" end |
.extract_direct_url(url) ⇒ Object
67 68 69 70 71 |
# File 'lib/leechtop_downloader/client.rb', line 67 def self.extract_direct_url(url) html = fetch_html(url) tokens = parse_tokens(html) fetch_ajax_direct_link(tokens) end |
.extract_page_links(url) ⇒ Object
135 136 137 138 139 140 141 142 143 |
# File 'lib/leechtop_downloader/client.rb', line 135 def self.extract_page_links(url) html = fetch_html(url) document = Nokogiri::HTML(html, nil, 'UTF-8') document.css('a').filter_map do |a| href = a['href'] href if href&.match?(%r{^https?://(?:www\.)?leechtop\.com/}) end end |
.fetch_ajax_direct_link(tokens) ⇒ Object
108 109 110 111 112 113 114 115 116 |
# File 'lib/leechtop_downloader/client.rb', line 108 def self.fetch_ajax_direct_link(tokens) ajax_url = 'https://leechtop.com/wp-admin/admin-ajax.php' body = URI.encode_www_form({ action: 'z_do_ajax', _action: 'directDownload' }.merge(tokens)) post_response = Faraday.new(request: { open_timeout: 10, timeout: 60 }).post(ajax_url, body) raise "AJAX request failed: HTTP #{post_response.status}" unless post_response.status == 200 parse_ajax_response(post_response.body) end |
.fetch_html(url) ⇒ Object
77 78 79 80 81 82 |
# File 'lib/leechtop_downloader/client.rb', line 77 def self.fetch_html(url) response = Faraday.new(request: { open_timeout: 10, timeout: 60 }).get(url) raise "Failed to load page: HTTP #{response.status}" unless response.status == 200 response.body end |
.fetch_metadata(url) ⇒ Object
54 55 56 57 58 59 60 61 |
# File 'lib/leechtop_downloader/client.rb', line 54 def self.(url) html = fetch_html(url) document = Nokogiri::HTML(html, nil, 'UTF-8') h4 = document.at_css('h4.mb-2') filename = h4&.text&.strip || '' { html: html, filename: filename } end |
.parse_ajax_response(body) ⇒ Object
122 123 124 125 126 127 128 129 |
# File 'lib/leechtop_downloader/client.rb', line 122 def self.parse_ajax_response(body) json = JSON.parse(body) direct_link = json['mes'] raise "Server rejected download request: #{json}" if direct_link == 'no' || direct_link.nil? direct_link end |
.parse_tokens(html) ⇒ Object
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/leechtop_downloader/client.rb', line 88 def self.parse_tokens(html) document = Nokogiri::HTML(html, nil, 'UTF-8') = document.at_css('.go-download-direct') raise 'Could not find download button in HTML' unless nonce_match = html.match(/"nonce":"([^"]+)"/) raise 'Could not extract nonce from page' unless nonce_match { p: T.must(['data-p']), mb: T.must(['data-mb']), nonce: T.must(nonce_match[1]) } end |