├── commiter.yml
├── download.bat
├── .gitignore
├── update.sh
├── templates.rb
├── config.json
├── page_template.html
├── downloader.rb
├── redownload.rb
├── mangaconfig.rb
├── LNDownloader.rb
└── MangaDownloader.rb
/commiter.yml:
--------------------------------------------------------------------------------
1 | convention: symphony
2 |
--------------------------------------------------------------------------------
/download.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | downloader.rb %*
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | test.rb
2 | urls.txt
3 | input.txt
4 |
--------------------------------------------------------------------------------
/update.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/bash
2 | ruby downloader.rb
3 |
--------------------------------------------------------------------------------
/templates.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | TEMPLATE_HTML = File.read("page_template.html")
4 |
--------------------------------------------------------------------------------
/config.json:
--------------------------------------------------------------------------------
1 | {
2 | "manganelo.com": {
3 | "ln": false,
4 | "chapter":".row-content-chapter a","page":".container-chapter-reader img","page1": "img"
5 | },
6 | "www.readlightnovel.org": {
7 | "ln": true,
8 | "chapter":"#accordion .tab-content li a","page":".chapter-content3 .desc"
9 | },
10 | "jpmtl.com": {
11 | "ln": true,
12 | "chapter":".book-ccontent a","page":"article"
13 | },
14 | "mangakakalots.com": {
15 | "ln": false,
16 | "chapter":"#chapter .chapter-list a","page":"img"
17 | }
18 | }
--------------------------------------------------------------------------------
/page_template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | Chapter {{chapter_index}} · {{mange_title}}
8 |
9 |
70 |
71 |
72 |
73 |
74 | {{button}}
75 |
76 | {{body}}
77 |
78 |
79 |
80 |
--------------------------------------------------------------------------------
/downloader.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require 'optparse'
5 | require 'json'
6 |
7 | require_relative 'MangaConfig'
8 | require_relative 'MangaDownloader'
9 | require_relative 'LNDownloader'
10 |
11 | MANGA_DIR = 'z:/Books/Manga'
12 | SELECTOR_CONFIG = JSON.parse(File.read(File.join(__dir__, 'config.json')))
13 |
14 | $messages = []
15 | def update_selectors(config)
16 | config['selector'] = SELECTOR_CONFIG[URI(config['url']).host]
17 | config
18 | end
19 |
20 | def download(config, _config_path)
21 | config = update_selectors(config)
22 |
23 | if config['ln']
24 | download = LNDownloader.new(config)
25 | else
26 | download = MangaDownloader.new(config)
27 | end
28 | system('rm urls.txt') if File.exist?('urls.txt')
29 | $messages << "Downloaded [#{config['title']}]" if download.download
30 | end
31 |
32 | def download_manga(title)
33 | [
34 | File.join(MANGA_DIR, title, 'Manga', title + ' - Manga.json'),
35 | File.join(
36 | MANGA_DIR,
37 | title,
38 | 'Light Novel - WEB',
39 | title + ' - Light Novel.json'
40 | )
41 | ].each do |config_path|
42 | if File.exist?(config_path)
43 | config = JSON.parse(File.read(config_path))
44 | download(config, config_path)
45 | end
46 | end
47 | end
48 |
49 | if ARGV.empty?
50 | while true
51 | config = MangaConfig.new
52 | download(config.get, config.config_path)
53 | end
54 | elsif ARGV.include? '-u'
55 | manga =
56 | Dir.entries(MANGA_DIR)[2..-1].select do |e|
57 | File.directory?(File.join(MANGA_DIR, e))
58 | end
59 |
60 | manga.each do |title|
61 | download_manga(title)
62 | end
63 | elsif ARGV.include? '-d'
64 | title = ARGV.last
65 | download_manga(title)
66 | end
67 |
68 | puts $messages unless $messages.empty?
69 |
--------------------------------------------------------------------------------
/redownload.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require 'optparse'
5 | require 'json'
6 |
7 | def manga_dir
8 | 'z:/Books/Manga'
9 | end
10 |
11 | def pad_num(num)
12 | num.to_s.rjust(4, '0')
13 | end
14 |
15 | def save_links_aria2c(list)
16 | download =
17 | list.flatten.map! do |url|
18 | [
19 | url['url'],
20 | ' dir=' + url['directory'],
21 | ' out=' + url['filename'].split('&')[0]
22 | ].join("\n")
23 | end
24 |
25 | out = File.open('urls.txt', 'w')
26 | out.puts download.join("\n")
27 | out.close
28 |
29 | unless list.empty?
30 | system(
31 | 'aria2c --check-certificate=false --auto-file-renaming=false --continue=true -i urls.txt'
32 | )
33 | end
34 | end
35 |
36 | def download(config, _config_path)
37 | download_list = []
38 | manga_name = config['name']
39 | puts manga_name
40 | manga_type = config['ln'] ? 'Light Novel' : 'Manga'
41 | config['chapters']['items'].each do |chapter|
42 | chapter['items'].each do |image|
43 | download_list <<
44 | {
45 | 'directory' =>
46 | "#{manga_dir}/#{manga_name}/#{manga_type}/Chapter #{pad_num(chapter["chapter"])}",
47 | 'filename' => "Page #{image["number"]}.jpg",
48 | 'url' => image["url"]
49 | }
50 | end
51 | end
52 | save_links_aria2c(download_list)
53 | exit
54 | end
55 |
56 | manga =
57 | Dir.entries(manga_dir)[2..-1].select do |e|
58 | File.directory?(File.join(manga_dir, e))
59 | end
60 |
61 | manga.each do |m|
62 | config_path = File.join(manga_dir, m, 'Manga', m + ' - Manga.json')
63 |
64 | next if !File.exist?(config_path)
65 | config = JSON.parse(File.read(config_path))
66 |
67 | if !config['ln']
68 | download(config, config_path)
69 | system('rm urls.txt') if File.exist?('urls.txt')
70 | end
71 | end
72 |
--------------------------------------------------------------------------------
/mangaconfig.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # frozen_string_literal: true
3 |
4 | require 'json'
5 | require 'fileutils'
6 |
7 | class MangaConfig
8 | def initialize
9 | @prefix = 'z:/Books/Manga'
10 | @selectors = JSON.parse(File.read(File.join(__dir__, 'config.json')))
11 | @manga_config = config_create_new
12 | config_save
13 | end
14 |
15 | def get
16 | @manga_config
17 | end
18 |
19 | def config_save
20 | FileUtils.mkpath(config_dir) unless Dir.exist?(config_dir)
21 | out = File.open(config_path, 'w')
22 | out.puts @manga_config.to_json
23 | out.close
24 | end
25 |
26 | def normalize(title)
27 | title.gsub(%r{[\\\/\:\*\?\"\<\>\|]+}, ' - ').gsub(/\r\n/im, ' ').gsub(
28 | /[ ]{2,}/im,
29 | ' '
30 | )
31 | end
32 |
33 | def manga_name
34 | @manga_config['name']
35 | end
36 |
37 | def manga_type
38 | @manga_config['ln'] ? 'Light Novel' : 'Manga'
39 | end
40 |
41 | def manga_folder
42 | @manga_config['ln'] ? 'Light Novel - WEB' : 'Manga'
43 | end
44 |
45 | def config_filename
46 | manga_name + " - #{manga_type}.json"
47 | end
48 |
49 | def config_dir
50 | File.join(@prefix, manga_name, manga_folder)
51 | end
52 |
53 | def manga_dir
54 | config_dir
55 | end
56 |
57 | def config_path
58 | File.join(config_dir, config_filename)
59 | end
60 |
61 | def config_create_new
62 | puts 'Enter title of manga: '
63 | title = STDIN.gets.chomp
64 | while title.empty?
65 | puts 'Enter title of manga: '
66 | title = STDIN.gets.chomp
67 | end
68 |
69 | puts 'Enter url of manga: '
70 | url = STDIN.gets.chomp
71 | while url.empty?
72 | puts 'Enter url of manga: '
73 | url = STDIN.gets.chomp
74 | end
75 |
76 | if @selectors.key?(URI(url).host)
77 | ln = @selectors[URI(url).host]['ln']
78 | else
79 | puts 'Is this Light Novel? [y/n, default = n]: '
80 | ln = STDIN.gets.chomp
81 | ln = !ln.empty? ? ln.downcase.include?('y') : false
82 | end
83 | puts "This is a #{ln ? 'Light Novel' : 'Manga'}"
84 |
85 | puts 'Enter index_start[default = 1]: '
86 | input = STDIN.gets.chomp
87 | index_start = input.empty? ? 1 : input.to_i
88 |
89 | pre_selected = @selectors[URI(url).host]['chapter']
90 | puts "Enter Selector for chapter[default = '#{pre_selected}']: "
91 | input = STDIN.gets.chomp
92 | chapter_selector = input.empty? ? pre_selected : input
93 |
94 | pre_selected = @selectors[URI(url).host]['page']
95 | puts "Enter Selector for page[default = '#{pre_selected}']: "
96 | input = STDIN.gets.chomp
97 | page_selector = input.empty? ? pre_selected : input
98 |
99 | # puts "Enter Selector for cover[default = '.manga-info-pic img']: "
100 | # input = STDIN.gets.chomp
101 | # cover_selector = input.empty? ? ".manga-info-pic img" : input
102 |
103 | {
104 | 'host' => URI(url).host,
105 | 'title' => title.gsub(/\r\n/im, ' ').gsub(/[ ]{2,}/im, ' '),
106 | 'url' => url,
107 | 'ln' => ln,
108 | 'name' => normalize(title),
109 | 'chapters' => {
110 | 'index_start' => index_start,
111 | 'index_end' => 0,
112 | 'count' => 0,
113 | 'items' => []
114 | },
115 | 'selector' => { 'chapter' => chapter_selector, 'page' => page_selector }
116 | }
117 | end
118 | end
119 |
--------------------------------------------------------------------------------
/LNDownloader.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'mechanize'
4 | require 'nokogiri'
5 | require 'open-uri'
6 | require 'json'
7 | require 'thread'
8 |
9 | require 'http'
10 | require 'to_duration'
11 | require 'tty-logger'
12 |
13 | require_relative 'templates'
14 |
15 | class LNDownloader
16 | def initialize(options)
17 | @start = Time.now
18 | @logger = TTY::Logger.new { |config| config.level = :debug } # or "INFO" or TTY::Logger::INFO_LEVEL
19 | @prefix = 'z:/Books/Manga'
20 | @manga_config = options
21 | @download_list = []
22 | @queue = Queue.new
23 | @threads = []
24 | end
25 |
26 | def manga_title
27 | @manga_config['title']
28 | end
29 |
30 | def manga_name
31 | @manga_config['name']
32 | end
33 |
34 | def manga_type
35 | @manga_config['ln'] ? 'Light Novel' : 'Manga'
36 | end
37 |
38 | def config_filename
39 | manga_name + " - #{manga_type}.json"
40 | end
41 |
42 | def manga_folder
43 | @manga_config['ln'] ? 'Light Novel - WEB' : 'Manga'
44 | end
45 |
46 | def config_dir
47 | File.join(@prefix, manga_name, manga_folder)
48 | end
49 |
50 | def config_path
51 | File.join(config_dir, config_filename)
52 | end
53 |
54 | def config_save
55 | Dir.mkdir(config_dir) unless Dir.exist?(config_dir)
56 | out = File.open(config_path, 'w')
57 | out.puts @manga_config.to_json
58 | out.close
59 | end
60 |
61 | def log_i(txt)
62 | @logger.info(manga_name, txt)
63 | end
64 |
65 | def log(txt)
66 | @logger.debug(manga_name, txt)
67 | end
68 |
69 | def page_fetch(url)
70 | log(url)
71 | Nokogiri::HTML.parse(HTTP.headers('User-Agent' => 'Curl').get(url).to_s)
72 | end
73 |
74 | def chapter_exist(chapter)
75 | itexist =
76 | @manga_config['chapters']['items'].select do |e|
77 | e['url'] == chapter[:url]
78 | end
79 |
80 | itexist.length > 0
81 | end
82 |
83 | def config_push_chapter(chapter)
84 | if !chapter_exist(chapter)
85 | @manga_config['chapters']['items'] << chapter
86 | @manga_config['chapters']['count'] =
87 | @manga_config['chapters']['items'].length
88 |
89 | config_save
90 | end
91 | end
92 |
93 | def fetch_manga_page
94 | doc = page_fetch(@manga_config['url'])
95 | chapters = doc.css(@manga_config['selector']['chapter']).to_a
96 | log_i("Found #{chapters.length} chapters")
97 | _index = @manga_config['chapters']['index_start'].to_i
98 | chapters.map! do |e|
99 | url = e['href']
100 | if @manga_config['host'].include?('jpmtl.com')
101 | url = 'https://' + @manga_config['host'] + e['href']
102 | end
103 | data = { chapter: _index, title: e.text, url: url }
104 | _index = _index + 1
105 | data
106 | end
107 | end
108 |
109 | def fetch_chapter_page(url)
110 | doc = page_fetch(url)
111 | page = doc.css(@manga_config['selector']['page']).to_a
112 |
113 | page.each { |elm| elm.search('.//script').remove }
114 |
115 | page.map!(&:to_s)
116 | end
117 |
118 | def save_links_aria2c(list)
119 | download =
120 | list.flatten.map! do |url|
121 | [
122 | url['url'],
123 | ' dir=' + url['directory'],
124 | ' out=' + url['filename'].split('&')[0]
125 | ].join("\n")
126 | end
127 |
128 | out = File.open('urls.txt', 'w')
129 | out.puts download.join("\n")
130 | out.close
131 |
132 | log('Downloading images')
133 | if !list.empty?
134 | system('aria2c --auto-file-renaming=false --continue=true -q -i urls.txt')
135 | end
136 | end
137 |
138 | def file_flush_data(filepath, data, write_type = 'w')
139 | out = File.open(filepath, write_type)
140 | out.puts data
141 | out.close
142 | end
143 |
144 | def pad_num(num)
145 | num.to_s.rjust(4, '0')
146 | end
147 |
148 | def page_html_generate(content, chapter, chapter_total)
149 | chapter_num = chapter['chapter']
150 |
151 | buttons = []
152 | if chapter_num > @manga_config['chapters']['index_start']
153 | buttons <<
154 | "◀
"
157 | end
158 | buttons <<
159 | "▶
"
162 |
163 | body = "#{content.join("\n")}"
164 |
165 | document = TEMPLATE_HTML.gsub('{{chapter_index}}', chapter_num.to_s)
166 | document = document.gsub('{{mange_title}}', manga_title)
167 | document = document.gsub('{{button}}', buttons.join("\n"))
168 | unless manga_title.include?('Overgeared') &&
169 | body.match?(/Chapter\s+\d+\-\d+/)
170 | document = document.gsub('{{body}}', body)
171 | end
172 |
173 | Dir.mkdir(config_dir) unless Dir.exist?(config_dir)
174 |
175 | html_page = "#{config_dir}/Chapter #{pad_num(chapter_num)}.html"
176 | file_flush_data(html_page, document, 'w') unless File.exist?(html_page)
177 | end
178 |
179 | def page_json_generate(content, chapter, _chapter_total)
180 | chapter_num = chapter['chapter']
181 |
182 | document = content.to_json
183 |
184 | Dir.mkdir(config_dir) unless Dir.exist?(config_dir)
185 |
186 | html_page = "#{config_dir}/Chapter #{pad_num(chapter_num)}.json"
187 | file_flush_data(html_page, document, 'w') unless File.exist?(html_page)
188 | end
189 |
190 | def parallel
191 | 2.times do
192 | @threads <<
193 | Thread.new do
194 | # loop until there are no more things to do
195 | until @queue.empty?
196 | # pop with the non-blocking flag set, this raises
197 | # an exception if the queue is empty, in which case
198 | # work_unit will be set to nil
199 | work_unit = @queue.pop
200 | if !work_unit.nil?
201 | chapter = work_unit[:data]
202 | total = work_unit[:total]
203 | chapter_url = chapter[:url]
204 | chapter_content = fetch_chapter_page(chapter_url)
205 |
206 | chapter_item = {
207 | 'url' => chapter[:url],
208 | 'chapter' => chapter[:chapter],
209 | 'title' => chapter[:title]
210 | }
211 | chapter_item_json = {
212 | 'url' => chapter[:url],
213 | 'chapter' => chapter[:chapter],
214 | 'title' => chapter[:title],
215 | 'items' => chapter_content
216 | }
217 |
218 | config_push_chapter(chapter_item)
219 |
220 | page_html_generate(chapter_content, chapter_item, total)
221 | page_json_generate(chapter_item_json, chapter_item, total)
222 | end
223 | end # when there is no more work, the thread will stop
224 | end
225 | end
226 |
227 | # wait until all threads have completed processing
228 | @threads.each(&:join)
229 | end
230 |
231 | def download
232 | log('Getting manga page')
233 |
234 | chapters = fetch_manga_page
235 |
236 | @manga_config['chapters']['index_end'] = chapters.length
237 |
238 | if chapters.length > @manga_config['chapters']['count']
239 |
240 | else
241 | log('No new chapters found')
242 | return false
243 | end
244 |
245 | chapters.select! { |e| !chapter_exist(e) }
246 | chapters.each { |e| @queue << { data: e, total: chapters.length } }
247 |
248 | parallel
249 |
250 | config_save
251 | log("Finish downloading in #{(Time.now - @start)}s")
252 |
253 | return true
254 | end
255 | end
256 |
--------------------------------------------------------------------------------
/MangaDownloader.rb:
--------------------------------------------------------------------------------
1 | #!/usr/bin/ruby
2 |
3 | require 'mechanize'
4 | require 'nokogiri'
5 | require 'open-uri'
6 | require 'json'
7 |
8 | require 'http'
9 | require 'to_duration'
10 | require 'tty-logger'
11 |
12 | require_relative 'templates'
13 |
14 | class MangaDownloader
15 | def initialize(config)
16 | @start = Time.now
17 | @logger = TTY::Logger.new do |config|
18 | config.level = :debug # or "INFO" or TTY::Logger::INFO_LEVEL
19 | end
20 | @prefix = 'z:/Books/Manga'
21 | @manga_config = config
22 | @download_list = []
23 | @queue = Queue.new
24 | @threads = []
25 | end
26 |
27 | def manga_title
28 | @manga_config['title']
29 | end
30 |
31 | def manga_name
32 | @manga_config['name']
33 | end
34 |
35 | def manga_type
36 | @manga_config['ln'] ? 'Light Novel' : 'Manga'
37 | end
38 |
39 | def config_filename
40 | manga_name + " - #{manga_type}.json"
41 | end
42 |
43 | def config_dir
44 | File.join(@prefix, manga_name, manga_type)
45 | end
46 |
47 | def manga_dir
48 | config_dir
49 | end
50 |
51 | def config_path
52 | File.join(config_dir, config_filename)
53 | end
54 |
55 | def config_save
56 | Dir.mkdir(config_dir) if !Dir.exist?(config_dir)
57 | out = File.open(config_path, 'w')
58 | out.puts @manga_config.to_json
59 | out.close
60 | end
61 |
62 | def log_i(txt)
63 | @logger.info(manga_name, txt)
64 | end
65 |
66 | def log(txt)
67 | @logger.debug(manga_name, txt)
68 | end
69 |
70 | def page_fetch(url)
71 | html = HTTP.get(url, {
72 | headers: {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.61 Safari/537.36'}
73 | }).to_s
74 | Nokogiri::HTML(
75 | html
76 | .gsub('', '')
78 | .gsub('data-src=', 'src=')
79 | )
80 | end
81 |
82 | def chapter_exist(chapter)
83 | itexist =
84 | @manga_config['chapters']['items'].select do |e|
85 | e['url'] == chapter[:url]
86 | end
87 |
88 | itexist.length > 0
89 | end
90 |
91 | def config_push_chapter(chapter)
92 | if !chapter_exist(chapter)
93 | @manga_config['chapters']['items'] << chapter
94 | @manga_config['chapters']['count'] =
95 | @manga_config['chapters']['items'].length
96 | end
97 | end
98 |
99 | def fetch_manga_page
100 | doc = page_fetch(@manga_config['url'])
101 | chapters = doc.css(@manga_config['selector']['chapter']).to_a.reverse
102 | log_i("Found #{chapters.length} chapters")
103 | index = @manga_config['chapters']['index_start'].to_i
104 | chapters.map! do |e|
105 | data = {
106 | chapter: index,
107 | title: e['title'],
108 | url: e['href'].gsub('?style=paged', '?style=list')
109 | }
110 | index += 1
111 | data
112 | end
113 | end
114 |
115 | def fetch_chapter_page(url)
116 | doc = page_fetch(url)
117 | img = doc.css(@manga_config['selector']['page']).to_a
118 | img = doc.css(@manga_config['selector']['page1']).to_a if img.length < 3
119 |
120 | index = 0
121 | images = []
122 | img.each do |e|
123 | index += 1
124 |
125 | images << { number: index, url: e['src'] }
126 | end
127 |
128 | images
129 | end
130 |
131 | def save_links_aria2c(list)
132 | download =
133 | list.flatten.map! do |url|
134 | [
135 | url['url'],
136 | ' dir=' + url['directory'],
137 | ' out=' + url['filename'].split('&')[0]
138 | ].join("\n")
139 | end
140 |
141 | out = File.open('urls.txt', 'a')
142 | out.puts download.join("\n")
143 | out.close
144 |
145 | log('Downloading images')
146 | if !list.empty?
147 | system(
148 | 'aria2c --check-certificate=false --auto-file-renaming=false --continue=true -j8 -x16 -i urls.txt'
149 | )
150 | end
151 | end
152 |
153 | def file_flush_data(filename, data, write_type = 'w')
154 | out = File.open(File.join(@prefix, filename), write_type)
155 | out.puts data
156 | out.close
157 | end
158 |
159 | def pad_num(num)
160 | num.to_s.rjust(4, '0')
161 | end
162 |
163 | def page_html_generate(images, chapter, chapter_total)
164 | chapter_num = chapter['chapter']
165 |
166 | buttons = []
167 | if chapter_num > @manga_config['chapters']['index_start']
168 | buttons <<
169 | "◀
"
172 | end
173 | buttons <<
174 | "▶
"
177 |
178 | img =
179 | images.map do |e|
180 | "
"
183 | end
184 |
185 | document = TEMPLATE_HTML.gsub('{{chapter_index}}', chapter_num.to_s)
186 | document = document.gsub('{{mange_title}}', manga_title)
187 | document = document.gsub('{{button}}', buttons.join("\n"))
188 | document = document.gsub('{{body}}', img.join("\n"))
189 |
190 | Dir.mkdir(manga_dir) unless Dir.exist?(manga_dir)
191 |
192 | html_page =
193 | "#{manga_name}/#{manga_type}/Chapter #{pad_num(chapter_num)}.html"
194 | file_flush_data(html_page, document, 'w') unless File.exist?(html_page)
195 | end
196 |
197 | def parallel
198 | 1.times do
199 | @threads <<
200 | Thread.new do
201 | # loop until there are no more things to do
202 | until @queue.empty?
203 | # pop with the non-blocking flag set, this raises
204 | # an exception if the queue is empty, in which case
205 | # work_unit will be set to nil
206 | work_unit =
207 | begin
208 | @queue.pop(true)
209 | rescue StandardError
210 | nil
211 | end
212 | if work_unit
213 | chapter = work_unit[:data]
214 | total = work_unit[:total]
215 | chapter_url = chapter[:url]
216 | chapter_images = fetch_chapter_page(chapter_url)
217 | log(
218 | "Chapter #{chapter[:chapter]} has #{
219 | chapter_images.length
220 | } pages"
221 | )
222 |
223 | chapter_item = {
224 | 'url' => chapter[:url],
225 | 'chapter' => chapter[:chapter],
226 | 'title' => chapter[:title],
227 | 'items' => chapter_images,
228 | 'count' => chapter_images.length
229 | }
230 |
231 | config_push_chapter(chapter_item)
232 |
233 | chapter_images.each do |image|
234 | @download_list <<
235 | {
236 | 'directory' =>
237 | "#{@prefix}/#{manga_name}/#{manga_type}/Chapter #{
238 | pad_num(chapter[:chapter])
239 | }",
240 | 'filename' => "Page #{image[:number]}.jpg",
241 | 'url' => image[:url]
242 | }
243 | end
244 |
245 | page_html_generate(chapter_images, chapter_item, total)
246 | end
247 | end # when there is no more work, the thread will stop
248 | end
249 | end
250 |
251 | # wait until all threads have completed processing
252 | @threads.each(&:join)
253 | end
254 |
255 | def download
256 | log('Getting manga page')
257 |
258 | chapters = fetch_manga_page
259 |
260 | @manga_config['chapters']['index_end'] = chapters.length
261 |
262 | if chapters.length > @manga_config['chapters']['count']
263 |
264 | else
265 | log('No new chapters found')
266 | return false
267 | end
268 |
269 | chapters.reject! { |e| chapter_exist(e) }
270 | chapters.each { |e| @queue << { data: e, total: chapters.length } }
271 |
272 | parallel
273 |
274 | log("Found #{@download_list.length} images for download")
275 |
276 | config_save
277 | save_links_aria2c(@download_list)
278 |
279 | log("Finish downloading in #{(Time.now - @start)}s")
280 |
281 | true
282 | end
283 | end
284 |
--------------------------------------------------------------------------------