mangdown 0.20.8 → 0.21.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +15 -10
- data/db/migrate/001_create_manga_table.rb +12 -0
- data/lib/mangdown.rb +68 -20
- data/lib/mangdown/adapter/manga_bat.rb +148 -0
- data/lib/mangdown/adapter/mangareader.rb +119 -91
- data/lib/mangdown/chapter.rb +27 -57
- data/lib/mangdown/client.rb +30 -53
- data/lib/mangdown/db.rb +27 -0
- data/lib/mangdown/db/manga.rb +9 -0
- data/lib/mangdown/manga.rb +25 -29
- data/lib/mangdown/page.rb +17 -13
- data/lib/mangdown/support/cbz.rb +1 -2
- data/lib/mangdown/support/logging.rb +1 -0
- data/lib/mangdown/support/tools.rb +18 -10
- data/lib/mangdown/version.rb +1 -1
- data/test/lib/mangdown/chapter_test.rb +18 -74
- data/test/lib/mangdown/manga_test.rb +11 -115
- data/test/lib/mangdown/support/cbz_test.rb +21 -9
- data/test/lib/mangdown/support/equality_test.rb +9 -2
- data/test/lib/mangdown/support/logging_test.rb +5 -2
- data/test/lib/mangdown/support/tools_test.rb +19 -6
- data/test/lib/mangdown_test.rb +35 -22
- data/test/support/test_adapter.rb +63 -83
- data/test/test_helper.rb +49 -1
- metadata +66 -14
- data/lib/mangdown/adapter.rb +0 -87
- data/lib/mangdown/adapter/proxy.rb +0 -44
- data/lib/mangdown/manga_list.rb +0 -43
- data/lib/mangdown/md_hash.rb +0 -73
- data/lib/mangdown/support/properties.rb +0 -50
- data/test/lib/mangdown/adapter_test.rb +0 -117
- data/test/lib/mangdown/manga_list_test.rb +0 -50
- data/test/lib/mangdown/support/properties_test.rb +0 -59
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9dd954ee70668eaf60bdb7666da399247cab3b12e5149bc58cabb1e1e69907d1
|
|
4
|
+
data.tar.gz: 4e6f7bac16b8537de8a54a80afd60c0b86fcb72c3e72e9c125106ca2fa7f7aa9
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: abbeef647bd90011460b32610a71ff2d0023450f50e64f9d2a0a1f31c5a5a0e78a7287ffafecd24cea3f421bd0738ca48828b5b70933983412af86945f6067a6
|
|
7
|
+
data.tar.gz: c9ee0906dbb2e26bb84be9f7a760cdbcf511420b7234bdbeffe601fbe70c93e229067aa3c16ee86649ef8da873f9682777b84f94f2be716609914eee36294c1b
|
data/README.md
CHANGED
|
@@ -1,33 +1,35 @@
|
|
|
1
|
-
## Adapters
|
|
2
|
-
Check out lib/mangdown/
|
|
1
|
+
## Adapters
|
|
2
|
+
Check out lib/mangdown/adapters/mangareader.rb and lib/mangdown/adapters/mangabat.rb for examples of how to build an adapter.
|
|
3
3
|
|
|
4
4
|
### Register an adapter
|
|
5
5
|
|
|
6
6
|
```
|
|
7
7
|
# Register an adapter (AdapterClass) with the name :name
|
|
8
|
-
Mangdown.register_adapter(:name, AdpaterClass)
|
|
8
|
+
Mangdown.register_adapter(:name, AdpaterClass.new)
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
### Bundled adapters
|
|
12
|
-
There
|
|
12
|
+
There are only two adapters bundled with mangdown, but it is fairly simple to create one, so go ahead and give it a try. Feel free to file an issue if you have any problems.
|
|
13
13
|
|
|
14
|
-
There is a simple built-in client, "
|
|
14
|
+
There is a simple built-in client, "Mangdown::Client", that you can use for finding manga:
|
|
15
15
|
|
|
16
16
|
```ruby
|
|
17
17
|
require 'mangdown/client'
|
|
18
18
|
|
|
19
19
|
# Search for an exact match
|
|
20
|
-
results =
|
|
20
|
+
results = Mangdown::Client.find("Dragon Ball")
|
|
21
21
|
|
|
22
22
|
# Or if you need more flexibilty when searching for a manga,
|
|
23
|
-
# use
|
|
24
|
-
results =
|
|
23
|
+
# use the db models directly
|
|
24
|
+
results = Mangdown::DB::Manga.where(name: 'Bleach').map do |record|
|
|
25
|
+
Mangdown.manga(record.url)
|
|
26
|
+
end
|
|
25
27
|
|
|
26
28
|
# Get a Mangdown::Manga object
|
|
27
|
-
manga = results.first
|
|
29
|
+
manga = results.first
|
|
28
30
|
|
|
29
31
|
# Get a chapter count
|
|
30
|
-
manga.
|
|
32
|
+
manga.chapter.length
|
|
31
33
|
|
|
32
34
|
# Download everything
|
|
33
35
|
manga.download
|
|
@@ -35,6 +37,9 @@ manga.download
|
|
|
35
37
|
# Download a specific range
|
|
36
38
|
manga.download(0, 99)
|
|
37
39
|
|
|
40
|
+
# Download to a specific dir
|
|
41
|
+
manga.download_to('path/to/downloads', 0, 99)
|
|
42
|
+
|
|
38
43
|
# Convert all downloaded chapters to CBZ
|
|
39
44
|
manga.cbz
|
|
40
45
|
|
data/lib/mangdown.rb
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require 'forwardable'
|
|
3
4
|
require 'addressable/uri'
|
|
4
5
|
require 'mimemagic'
|
|
5
6
|
require 'nokogiri'
|
|
@@ -10,47 +11,94 @@ require_relative 'mangdown/error'
|
|
|
10
11
|
|
|
11
12
|
require_relative 'mangdown/support/logging'
|
|
12
13
|
require_relative 'mangdown/support/equality'
|
|
13
|
-
require_relative 'mangdown/support/properties'
|
|
14
14
|
require_relative 'mangdown/support/tools'
|
|
15
15
|
require_relative 'mangdown/support/cbz'
|
|
16
16
|
require_relative 'mangdown/page'
|
|
17
17
|
require_relative 'mangdown/chapter'
|
|
18
18
|
require_relative 'mangdown/manga'
|
|
19
|
-
require_relative 'mangdown/manga_list.rb'
|
|
20
|
-
require_relative 'mangdown/md_hash'
|
|
21
19
|
|
|
22
|
-
require_relative 'mangdown/adapter'
|
|
23
|
-
require_relative 'mangdown/adapter/proxy'
|
|
24
20
|
require_relative 'mangdown/adapter/no_adapter_error'
|
|
25
21
|
require_relative 'mangdown/adapter/not_implemented_error'
|
|
26
|
-
require_relative 'mangdown/adapter/mangareader
|
|
22
|
+
require_relative 'mangdown/adapter/mangareader'
|
|
23
|
+
require_relative 'mangdown/adapter/manga_bat'
|
|
27
24
|
|
|
28
25
|
# Find, download and package manga from the web
|
|
29
26
|
module Mangdown
|
|
30
|
-
|
|
27
|
+
class <<self
|
|
28
|
+
include Logging
|
|
29
|
+
end
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
DOWNLOAD_DIR ||= Dir.home + '/manga'
|
|
33
32
|
|
|
34
|
-
def register_adapter(name, adapter)
|
|
33
|
+
def self.register_adapter(name, adapter)
|
|
35
34
|
adapters[name] = adapter
|
|
36
35
|
end
|
|
37
36
|
|
|
38
|
-
def
|
|
39
|
-
adapters
|
|
37
|
+
def self.adapters
|
|
38
|
+
@adapters ||= {}
|
|
40
39
|
end
|
|
41
40
|
|
|
42
|
-
def
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
def self.manga(uri_or_instance)
|
|
42
|
+
with_adapter(uri_or_instance, :manga) do |instance|
|
|
43
|
+
Mangdown::Manga.new(instance)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
def self.chapter(uri_or_instance)
|
|
48
|
+
with_adapter(uri_or_instance, :chapter) do |instance|
|
|
49
|
+
Mangdown::Chapter.new(instance)
|
|
50
|
+
end
|
|
51
|
+
end
|
|
47
52
|
|
|
48
|
-
|
|
53
|
+
def self.page(uri_or_instance)
|
|
54
|
+
with_adapter(uri_or_instance, :page) do |instance|
|
|
55
|
+
Mangdown::Page.new(instance)
|
|
56
|
+
end
|
|
49
57
|
end
|
|
50
58
|
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
# rubocop:disable Metrics/AbcSize
|
|
60
|
+
# rubocop:disable Metrics/MethodLength
|
|
61
|
+
def self.with_adapter(instance, instance_constructor)
|
|
62
|
+
if instance.is_a?(String)
|
|
63
|
+
adapter = adapter(instance)
|
|
64
|
+
instance = adapter.public_send(instance_constructor, instance)
|
|
65
|
+
else
|
|
66
|
+
adapter = adapter(instance.url)
|
|
67
|
+
klass = adapter.class.const_get(instance_constructor.to_s.capitalize)
|
|
68
|
+
instance = klass.new(instance.attributes)
|
|
69
|
+
end
|
|
70
|
+
yield(instance)
|
|
71
|
+
rescue Adapter::NoAdapterError
|
|
72
|
+
raise
|
|
73
|
+
rescue StandardError => error
|
|
74
|
+
logger.error(debug_error(error, adapter, instance))
|
|
75
|
+
raise Mangdown::Error, "Adapter failed: #{error.message}"
|
|
53
76
|
end
|
|
54
|
-
|
|
77
|
+
private_class_method :with_adapter
|
|
78
|
+
# rubocop:enable Metrics/AbcSize
|
|
79
|
+
# rubocop:enable Metrics/MethodLength
|
|
55
80
|
|
|
56
|
-
|
|
81
|
+
def self.adapter(uri)
|
|
82
|
+
adapter = adapters.values.find { |a| a.for?(uri) }
|
|
83
|
+
|
|
84
|
+
raise Adapter::NoAdapterError, uri unless adapter
|
|
85
|
+
|
|
86
|
+
adapter
|
|
87
|
+
end
|
|
88
|
+
private_class_method :adapter
|
|
89
|
+
|
|
90
|
+
def self.debug_error(error, adapter, instance)
|
|
91
|
+
{
|
|
92
|
+
msg: 'Adapter method failed',
|
|
93
|
+
adapter: adapter.class,
|
|
94
|
+
instance: instance,
|
|
95
|
+
error: error,
|
|
96
|
+
error_msg: error.message,
|
|
97
|
+
backtrace: error.backtrace
|
|
98
|
+
}.to_s
|
|
99
|
+
end
|
|
100
|
+
private_class_method :debug_error
|
|
101
|
+
|
|
102
|
+
register_adapter :mangareader, Mangdown::Mangareader.new
|
|
103
|
+
register_adapter :manga_bat, Mangdown::MangaBat.new
|
|
104
|
+
end
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'scrapework'
|
|
4
|
+
|
|
5
|
+
module Mangdown
|
|
6
|
+
# Adapter for mangabat
|
|
7
|
+
class MangaBat
|
|
8
|
+
ROOT = 'https://mangabat.com/'
|
|
9
|
+
CDNS = [
|
|
10
|
+
%r{^https://s\d.mkklcdnv\d.com/mangakakalot}
|
|
11
|
+
].freeze
|
|
12
|
+
|
|
13
|
+
def for?(uri)
|
|
14
|
+
uri.to_s.start_with?(ROOT) || cdn_uri?(uri)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def cdn_uri?(uri)
|
|
18
|
+
CDNS.any? { |cdn| uri.match?(cdn) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def manga_list
|
|
22
|
+
MangaList.load('https://mangabat.com/manga_list')
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def manga(url)
|
|
26
|
+
Manga.load(url)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def chapter(url)
|
|
30
|
+
Chapter.load(url)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def page(url)
|
|
34
|
+
Page.load(url)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# A manga list web page
|
|
38
|
+
class MangaList < Scrapework::Object
|
|
39
|
+
has_many :manga, class: 'Mangdown::MangaBat::Manga'
|
|
40
|
+
|
|
41
|
+
def each(*args, &block)
|
|
42
|
+
to_enum.each(*args, &block)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def to_enum
|
|
46
|
+
Enumerator.new do |yielder|
|
|
47
|
+
page = self
|
|
48
|
+
|
|
49
|
+
while page
|
|
50
|
+
page.manga.each { |manga| yielder << manga }
|
|
51
|
+
|
|
52
|
+
page = page.next_page
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
map 'manga' do |html|
|
|
58
|
+
html.css('.update_item h3 a').map do |a|
|
|
59
|
+
uri = URI.join(ROOT, a[:href]).to_s
|
|
60
|
+
|
|
61
|
+
{ url: uri, name: a.text.strip }
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
paginate do |html|
|
|
66
|
+
pages = html.css('.group-page a').to_a[1..-2]
|
|
67
|
+
current = pages.find_index { |p| p['class'] == 'pageselect' }
|
|
68
|
+
|
|
69
|
+
prev_page_link = pages[current - 1] if current
|
|
70
|
+
next_page_link = pages[current + 1] if current
|
|
71
|
+
|
|
72
|
+
prev_page = { url: prev_page_link['href'] } if prev_page_link
|
|
73
|
+
next_page = { url: next_page_link['href'] } if next_page_link
|
|
74
|
+
|
|
75
|
+
[prev_page, next_page]
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# A manga web page
|
|
80
|
+
class Manga < Scrapework::Object
|
|
81
|
+
attribute :name
|
|
82
|
+
|
|
83
|
+
has_many :chapters, class: 'Mangdown::MangaBat::Chapter'
|
|
84
|
+
|
|
85
|
+
map :name do |html|
|
|
86
|
+
html.css('h1.entry-title').text.strip
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
map :chapters do |html|
|
|
90
|
+
html.css('.chapter-list .row a').reverse.map.with_index do |chapter, i|
|
|
91
|
+
i += 1
|
|
92
|
+
padded_number = i.to_s.rjust(5, '0')
|
|
93
|
+
chapter_name = "#{name} #{padded_number}"
|
|
94
|
+
|
|
95
|
+
{ url: chapter['href'], name: chapter_name, number: i }
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# A manga chapter web page
|
|
101
|
+
class Chapter < Scrapework::Object
|
|
102
|
+
attribute :name
|
|
103
|
+
attribute :number, type: Integer
|
|
104
|
+
|
|
105
|
+
belongs_to :manga, class: 'Mangdown::MangaBat::Manga'
|
|
106
|
+
has_many :pages, class: 'Mangdown::MangaBat::Page'
|
|
107
|
+
|
|
108
|
+
map :name do |html|
|
|
109
|
+
name = html.at_css('h1.entry-title').text.strip
|
|
110
|
+
name.sub(/Chapter (\d+)/) { Regexp.last_match[1].rjust(5, '0') }
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
map :number do
|
|
114
|
+
_mapped_name.slice(/Chapter (\d+)/, 1)
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
map :manga do |html|
|
|
118
|
+
manga = html.at_css('.breadcrumbs_doc p span:nth-child(3) a')
|
|
119
|
+
|
|
120
|
+
{ url: manga['href'], name: manga.text.strip }
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
map :pages do |html|
|
|
124
|
+
html.css('.vung_doc img').map.with_index do |page, i|
|
|
125
|
+
i += 1
|
|
126
|
+
url = page['src']
|
|
127
|
+
padded_number = i.to_s.rjust(3, '0')
|
|
128
|
+
padded_chapter = number.to_s.rjust(5, '0')
|
|
129
|
+
name = "#{manga.name} #{padded_chapter}-#{padded_number}"
|
|
130
|
+
|
|
131
|
+
{ url: url, name: name, number: i }
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def hydra_opts
|
|
136
|
+
{ max_concurrency: 10 }
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
# A manga page image
|
|
141
|
+
class Page < Scrapework::Object
|
|
142
|
+
attribute :name
|
|
143
|
+
attribute :number, type: Integer
|
|
144
|
+
|
|
145
|
+
belongs_to :chapter, class: 'Mangdown::MangaBat::Chapter'
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -1,134 +1,162 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require '
|
|
3
|
+
require 'scrapework'
|
|
4
4
|
|
|
5
5
|
module Mangdown
|
|
6
|
-
#
|
|
7
|
-
class Mangareader
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
@root = 'https://www.mangareader.net'
|
|
6
|
+
# Adapter for mangareader
|
|
7
|
+
class Mangareader
|
|
8
|
+
ROOT = 'https://www.mangareader.net'
|
|
9
|
+
|
|
10
|
+
def for?(uri)
|
|
11
|
+
URI.parse(uri).host&.end_with?('mangareader.net')
|
|
12
|
+
rescue URI::Error
|
|
13
|
+
false
|
|
16
14
|
end
|
|
17
15
|
|
|
18
|
-
def
|
|
19
|
-
|
|
16
|
+
def manga_list
|
|
17
|
+
MangaList.load('https://www.mangareader.net/alphabetical')
|
|
20
18
|
end
|
|
21
19
|
|
|
22
|
-
def
|
|
23
|
-
|
|
20
|
+
def manga(url)
|
|
21
|
+
Manga.load(url)
|
|
24
22
|
end
|
|
25
23
|
|
|
26
|
-
def
|
|
27
|
-
|
|
24
|
+
def chapter(url)
|
|
25
|
+
Chapter.load(url)
|
|
28
26
|
end
|
|
29
27
|
|
|
30
|
-
def
|
|
31
|
-
|
|
28
|
+
def page(url)
|
|
29
|
+
Page.load(url)
|
|
32
30
|
end
|
|
33
31
|
|
|
34
|
-
#
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
uri = "#{root}#{a[:href]}"
|
|
38
|
-
manga = { uri: uri, name: a.text.strip.tr('/', ''), site: site }
|
|
32
|
+
# A mangareader manga list
|
|
33
|
+
class MangaList < Scrapework::Object
|
|
34
|
+
has_many :manga, class: 'Mangdown::Mangareader::Manga'
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
map :manga do |html|
|
|
37
|
+
html.css('ul.series_alpha li a').map do |a|
|
|
38
|
+
uri = "#{ROOT}#{a[:href]}"
|
|
43
39
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
40
|
+
{ url: uri, name: a.text.strip }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
47
43
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
uri = root + a[:href].sub(root, '')
|
|
52
|
-
chapter = { uri: uri, name: a.text.strip.tr('/', ''), site: site }
|
|
44
|
+
def each(&block)
|
|
45
|
+
manga.each(&block)
|
|
46
|
+
end
|
|
53
47
|
|
|
54
|
-
|
|
55
|
-
|
|
48
|
+
def to_enum
|
|
49
|
+
manga.to_enum
|
|
50
|
+
end
|
|
56
51
|
end
|
|
57
52
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
site: site }
|
|
64
|
-
end
|
|
53
|
+
# A mangareader manga
|
|
54
|
+
class Manga < Scrapework::Object
|
|
55
|
+
attribute :name
|
|
56
|
+
|
|
57
|
+
has_many :chapters, class: 'Mangdown::Mangareader::Chapter'
|
|
65
58
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
59
|
+
map :name do |html|
|
|
60
|
+
html.at_css('h2.aname').text.strip
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
map :chapters do |html|
|
|
64
|
+
html.css('div#chapterlist td a').map.with_index do |a, i|
|
|
65
|
+
uri = ROOT + a[:href]
|
|
66
|
+
|
|
67
|
+
{ url: uri, name: a.text.strip, number: i + 1 }
|
|
68
|
+
end
|
|
73
69
|
end
|
|
74
70
|
end
|
|
75
71
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
72
|
+
# A mangareader chapter
|
|
73
|
+
class Chapter < Scrapework::Object
|
|
74
|
+
attribute :name
|
|
75
|
+
attribute :number, type: Integer
|
|
76
|
+
|
|
77
|
+
belongs_to :manga, class: 'Mangdown::Mangareader::Manga'
|
|
78
|
+
has_many :page_views, class: 'Mangdown::Mangareader::PageView'
|
|
79
|
+
|
|
80
|
+
map :name do |html|
|
|
81
|
+
name = html.at_css('#mangainfo h1').text.strip
|
|
82
|
+
name.sub(/(\d+)$/) { Regexp.last_match[1].rjust(5, '0') }
|
|
81
83
|
end
|
|
82
84
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
+
map :number do |html|
|
|
86
|
+
_mapped_name.slice(/(\d+)$/, 1)
|
|
87
|
+
end
|
|
85
88
|
|
|
86
|
-
|
|
89
|
+
map :manga do |html|
|
|
90
|
+
manga = html.at_css('#mangainfo h2.c2 a')
|
|
87
91
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
name = chapter_manga_name
|
|
92
|
+
{
|
|
93
|
+
url: "#{ROOT}#{manga['href']}",
|
|
94
|
+
name: manga.text.strip.sub(/ Manga$/, '')
|
|
95
|
+
}
|
|
93
96
|
end
|
|
94
97
|
|
|
95
|
-
|
|
98
|
+
map :page_views do |html|
|
|
99
|
+
html.css('#selectpage select#pageMenu option').map.with_index do |op, i|
|
|
100
|
+
i += 1
|
|
101
|
+
uri = "#{ROOT}#{op['value']}"
|
|
102
|
+
padded_number = i.to_s.rjust(3, '0')
|
|
103
|
+
padded_chapter = number.to_s.rjust(5, '0')
|
|
104
|
+
name = "#{manga.name} #{padded_chapter}-#{padded_number}"
|
|
96
105
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
106
|
+
{ url: uri, name: name, number: i }
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def hydra_opts
|
|
111
|
+
{}
|
|
112
|
+
end
|
|
100
113
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
@name.sub(/\s(\d+)$/) { |num| ' ' + num.to_i.to_s.rjust(5, '0') }
|
|
104
|
-
else
|
|
105
|
-
doc.css('').text # Not implimented
|
|
106
|
-
end
|
|
114
|
+
def pages
|
|
115
|
+
return @pages if defined?(@pages)
|
|
107
116
|
|
|
108
|
-
|
|
117
|
+
threads = []
|
|
118
|
+
page_views.each do |page_view|
|
|
119
|
+
threads << Thread.new(page_view, &:page)
|
|
120
|
+
end
|
|
121
|
+
threads.each(&:join)
|
|
109
122
|
|
|
110
|
-
|
|
111
|
-
|
|
123
|
+
@pages = page_views.map(&:page)
|
|
124
|
+
end
|
|
112
125
|
end
|
|
113
126
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
doc.css('').text # Not implimented
|
|
119
|
-
end
|
|
127
|
+
# A mangareader page
|
|
128
|
+
class PageView < Scrapework::Object
|
|
129
|
+
attribute :name
|
|
130
|
+
attribute :number, type: Integer
|
|
120
131
|
|
|
121
|
-
|
|
132
|
+
belongs_to :chapter, class: 'Mangdown::Mangareader::Chapter'
|
|
133
|
+
has_one :page, class: 'Mangdown::Mangareader::Page'
|
|
122
134
|
|
|
123
|
-
|
|
124
|
-
|
|
135
|
+
alias uri url
|
|
136
|
+
|
|
137
|
+
map :chapter do |html|
|
|
138
|
+
name = html.at_css('.mangainfo h1').text.strip
|
|
139
|
+
op = html.css('#selectpage select#pageMenu option').first
|
|
140
|
+
|
|
141
|
+
{ url: "#{ROOT}#{op['href']}", name: name }
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
map :page do |html|
|
|
145
|
+
img = html.at_css('#imgholder img#img')
|
|
146
|
+
|
|
147
|
+
{ url: img['src'], name: name, number: number }
|
|
148
|
+
end
|
|
125
149
|
end
|
|
126
150
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
151
|
+
# A mangareader page
|
|
152
|
+
class Page < Scrapework::Object
|
|
153
|
+
attribute :name
|
|
154
|
+
attribute :number, type: Integer
|
|
155
|
+
|
|
156
|
+
belongs_to :page_view, class: 'Mangdown::Mangareader::PageView'
|
|
157
|
+
|
|
158
|
+
def chapter
|
|
159
|
+
page_view.chapter
|
|
132
160
|
end
|
|
133
161
|
end
|
|
134
162
|
end
|