mangdown 0.20.8 → 0.21.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- 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
data/lib/mangdown/chapter.rb
CHANGED
@@ -3,26 +3,26 @@
|
|
3
3
|
module Mangdown
|
4
4
|
# Mangdown chapter object, which holds pages
|
5
5
|
class Chapter
|
6
|
+
extend Forwardable
|
7
|
+
|
6
8
|
include Equality
|
7
|
-
include Enumerable
|
8
9
|
|
9
|
-
attr_reader :
|
10
|
-
|
10
|
+
attr_reader :chapter
|
11
|
+
|
12
|
+
def_delegators :chapter, :url, :name, :number
|
13
|
+
|
14
|
+
alias uri url
|
11
15
|
|
12
|
-
def initialize(
|
13
|
-
@name = name
|
14
|
-
@manga = manga
|
16
|
+
def initialize(chapter)
|
15
17
|
@chapter = chapter
|
16
|
-
@uri = Addressable::URI.escape(uri)
|
17
|
-
@pages = []
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
21
|
-
@pages.
|
20
|
+
def pages
|
21
|
+
@pages ||= chapter.pages.map { |page| Mangdown.page(page) }
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
25
|
-
|
24
|
+
def manga
|
25
|
+
@manga ||= Mangdown.manga(chapter.manga)
|
26
26
|
end
|
27
27
|
|
28
28
|
def path
|
@@ -31,8 +31,8 @@ module Mangdown
|
|
31
31
|
alias to_path path
|
32
32
|
|
33
33
|
def setup_path(dir = nil)
|
34
|
-
dir ||=
|
35
|
-
path =
|
34
|
+
dir ||= manga.path
|
35
|
+
path = Tools.file_join(dir, name)
|
36
36
|
path = Tools.valid_path_name(path)
|
37
37
|
@path = Tools.relative_or_absolute_path(path)
|
38
38
|
end
|
@@ -41,8 +41,11 @@ module Mangdown
|
|
41
41
|
CBZ.one(dir)
|
42
42
|
end
|
43
43
|
|
44
|
+
# rubocop:disable Metrics/AbcSize
|
45
|
+
# rubocop:disable Metrics/CyclomaticComplexity
|
46
|
+
# rubocop:disable Metrics/MethodLength
|
47
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
44
48
|
def download_to(dir = nil, opts = { force_download: false })
|
45
|
-
pages = map(&:to_page)
|
46
49
|
failed = []
|
47
50
|
succeeded = []
|
48
51
|
skipped = []
|
@@ -53,10 +56,13 @@ module Mangdown
|
|
53
56
|
setup_download_dir!(dir)
|
54
57
|
end
|
55
58
|
|
56
|
-
Tools.hydra_streaming(
|
59
|
+
Tools.hydra_streaming(
|
60
|
+
pages,
|
61
|
+
chapter.hydra_opts
|
62
|
+
) do |stage, page, data = nil|
|
57
63
|
case stage
|
58
64
|
when :failed
|
59
|
-
failed << page
|
65
|
+
failed << [page, data]
|
60
66
|
when :succeeded
|
61
67
|
succeeded << page
|
62
68
|
when :before
|
@@ -72,13 +78,10 @@ module Mangdown
|
|
72
78
|
|
73
79
|
{ failed: failed, succeeded: succeeded, skipped: skipped }
|
74
80
|
end
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
fetch_each_page { |page| @pages << page }
|
80
|
-
@pages.sort_by!(&:name)
|
81
|
-
end
|
81
|
+
# rubocop:enable Metrics/AbcSize
|
82
|
+
# rubocop:enable Metrics/CyclomaticComplexity
|
83
|
+
# rubocop:enable Metrics/MethodLength
|
84
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
82
85
|
|
83
86
|
private
|
84
87
|
|
@@ -86,38 +89,5 @@ module Mangdown
|
|
86
89
|
setup_path(dir)
|
87
90
|
FileUtils.mkdir_p(to_path) unless Dir.exist?(to_path)
|
88
91
|
end
|
89
|
-
|
90
|
-
def fetch_each_page
|
91
|
-
pages = build_page_hashes
|
92
|
-
page_data = Hash.new { |h, k| h[k] = +'' }
|
93
|
-
Tools.hydra_streaming(pages, adapter.hydra_opts) do |status, page, data = nil|
|
94
|
-
case status
|
95
|
-
when :before
|
96
|
-
true
|
97
|
-
when :body
|
98
|
-
page_data[page] << data
|
99
|
-
when :complete
|
100
|
-
page = get_page(page.uri, Nokogiri::HTML(page_data[page]))
|
101
|
-
yield(page)
|
102
|
-
end
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
def build_page_hashes
|
107
|
-
adapter.page_list.map do |page|
|
108
|
-
page[:chapter] = name
|
109
|
-
page[:manga] = manga
|
110
|
-
MDHash.new(page)
|
111
|
-
end
|
112
|
-
end
|
113
|
-
|
114
|
-
def get_page(uri, doc)
|
115
|
-
adapter = Mangdown.adapter!(uri, nil, doc)
|
116
|
-
page = adapter.page
|
117
|
-
page[:chapter] = name
|
118
|
-
page[:manga] = manga
|
119
|
-
|
120
|
-
MDHash.new(page)
|
121
|
-
end
|
122
92
|
end
|
123
93
|
end
|
data/lib/mangdown/client.rb
CHANGED
@@ -2,21 +2,24 @@
|
|
2
2
|
|
3
3
|
require_relative '../mangdown'
|
4
4
|
|
5
|
-
|
6
|
-
module M
|
7
|
-
DATA_FILE_PATH = Dir.home + '/.manga_list.yml'
|
8
|
-
HELP_FILE_PATH = File.expand_path(
|
9
|
-
'../../README.md', File.dirname(__FILE__)
|
10
|
-
)
|
5
|
+
require_relative 'db'
|
11
6
|
|
12
|
-
|
7
|
+
module Mangdown
|
8
|
+
# Simple client for Mangdown
|
9
|
+
module Client
|
10
|
+
class <<self
|
11
|
+
include Logging
|
12
|
+
end
|
13
|
+
|
14
|
+
module_function
|
13
15
|
|
14
|
-
class << self
|
15
16
|
# return a list of hash with :uri and :name of mangas found in list
|
16
17
|
def find(search)
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
filter = Sequel.lit('LOWER(name) LIKE ?', "%#{search.downcase}%")
|
19
|
+
order = Sequel[:name]
|
20
|
+
Mangdown::DB::Manga.where(filter).order(order).map do |manga|
|
21
|
+
Mangdown.manga(manga.url)
|
22
|
+
end
|
20
23
|
end
|
21
24
|
|
22
25
|
# cbz all subdirectories in a directory
|
@@ -26,51 +29,25 @@ module M
|
|
26
29
|
raise Mangdown::Error, "Failed to package #{dir}: #{error.message}"
|
27
30
|
end
|
28
31
|
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
# delete data file
|
35
|
-
def clean_up
|
36
|
-
File.delete(DATA_FILE_PATH) if File.exist?(DATA_FILE_PATH)
|
37
|
-
end
|
38
|
-
|
39
|
-
def manga_pages
|
40
|
-
@manga_pages ||= DEFAULT_MANGA_PAGES.dup
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
# convenience method to access the data file path
|
46
|
-
def path
|
47
|
-
DATA_FILE_PATH
|
48
|
-
end
|
49
|
-
|
50
|
-
# check if the data file is current
|
51
|
-
def file_current?(file)
|
52
|
-
File.exist?(file) && File.mtime(file) > (Time.now - 604_800)
|
53
|
-
end
|
32
|
+
# rubocop:disable Metrics/MethodLength
|
33
|
+
# load manga into sqlite db
|
34
|
+
def index_manga
|
35
|
+
count_before = Mangdown::DB::Manga.count
|
54
36
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
37
|
+
Mangdown.adapters.each do |name, adapters|
|
38
|
+
adapters.manga_list.each do |manga|
|
39
|
+
Mangdown::DB::Manga.find_or_create(
|
40
|
+
adapter: name,
|
41
|
+
url: manga.url,
|
42
|
+
name: manga.name
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
59
46
|
|
60
|
-
|
61
|
-
# otherwise fetch new data and write it to the data file
|
62
|
-
def current_manga_list
|
63
|
-
data = data_from_file
|
64
|
-
return Mangdown::MangaList.from_data(data) if data
|
47
|
+
count_after = Mangdown::DB::Manga.count
|
65
48
|
|
66
|
-
|
67
|
-
list = Mangdown::MDHash.new(uri: uri).to_manga_list
|
68
|
-
list.merge(manga)
|
69
|
-
end
|
70
|
-
File.open(path, 'w+') { |f| f.write(list.to_yaml) }
|
71
|
-
list
|
72
|
-
rescue StandardError => error
|
73
|
-
raise Mangdown::Error, "#{path} may be corrupt: #{error.message}"
|
49
|
+
logger.info("#{count_after} manga, #{count_after - count_before} new")
|
74
50
|
end
|
51
|
+
# rubocop:enable Metrics/MethodLength
|
75
52
|
end
|
76
53
|
end
|
data/lib/mangdown/db.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'sequel'
|
4
|
+
require 'sqlite3'
|
5
|
+
|
6
|
+
module Mangdown
|
7
|
+
# DB Connection
|
8
|
+
module DB
|
9
|
+
DB_MIGRATE = File.expand_path('../../db/migrate', __dir__)
|
10
|
+
DB_FILE = File.expand_path('../../db/mangdown.db', __dir__)
|
11
|
+
|
12
|
+
unless File.exist?(DB_FILE)
|
13
|
+
begin
|
14
|
+
SQLite3::Database.new(DB_FILE)
|
15
|
+
rescue StandardError
|
16
|
+
File.delete(DB_FILE)
|
17
|
+
raise
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
CONNECTION = Sequel.connect("sqlite://#{DB_FILE}")
|
22
|
+
Sequel.extension(:migration)
|
23
|
+
Sequel::Migrator.run(CONNECTION, DB_MIGRATE)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
require_relative 'db/manga'
|
data/lib/mangdown/manga.rb
CHANGED
@@ -3,17 +3,25 @@
|
|
3
3
|
module Mangdown
|
4
4
|
# Mangdown manga object, which holds chapters
|
5
5
|
class Manga
|
6
|
+
extend Forwardable
|
7
|
+
|
6
8
|
include Equality
|
7
|
-
include Enumerable
|
8
9
|
include Logging
|
9
10
|
|
10
|
-
|
11
|
-
|
11
|
+
attr_accessor :manga
|
12
|
+
|
13
|
+
def_delegators :manga, :url, :name
|
12
14
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
@
|
15
|
+
alias uri url
|
16
|
+
|
17
|
+
def initialize(manga)
|
18
|
+
@manga = manga
|
19
|
+
end
|
20
|
+
|
21
|
+
def chapters
|
22
|
+
@chapters ||= manga
|
23
|
+
.chapters
|
24
|
+
.map { |chapter| Mangdown.chapter(chapter) }
|
17
25
|
end
|
18
26
|
|
19
27
|
def cbz
|
@@ -24,7 +32,8 @@ module Mangdown
|
|
24
32
|
download_to(nil, *args)
|
25
33
|
end
|
26
34
|
|
27
|
-
#
|
35
|
+
# rubocop:disable Metrics/AbcSize
|
36
|
+
# rubocop:disable Metrics/MethodLength
|
28
37
|
def download_to(dir, start = 0, stop = -1, opts = { force_download: false })
|
29
38
|
start, stop = validate_indeces!(start, stop)
|
30
39
|
setup_download_dir!(dir)
|
@@ -32,16 +41,15 @@ module Mangdown
|
|
32
41
|
succeeded = []
|
33
42
|
skipped = []
|
34
43
|
|
35
|
-
chapters[start..stop].each do |
|
36
|
-
chapter = md_hash.to_chapter
|
44
|
+
chapters[start..stop].each do |chapter|
|
37
45
|
chapter_result = chapter.download_to(to_path, opts)
|
38
46
|
|
39
47
|
if chapter_result[:failed].any?
|
40
|
-
failed << chapter
|
48
|
+
failed << [chapter, chapter_result]
|
41
49
|
elsif chapter_result[:succeeded].any?
|
42
|
-
succeeded << chapter
|
50
|
+
succeeded << [chapter, chapter_result]
|
43
51
|
elsif chapter_result[:skipped].any?
|
44
|
-
skipped << chapter
|
52
|
+
skipped << [chapter, chapter_result]
|
45
53
|
end
|
46
54
|
|
47
55
|
next unless chapter_result[:failed].any?
|
@@ -52,12 +60,11 @@ module Mangdown
|
|
52
60
|
chapter: chapter.name
|
53
61
|
}.to_s)
|
54
62
|
end
|
55
|
-
{ failed: failed, succeeded: succeeded, skipped: skipped }
|
56
|
-
end
|
57
63
|
|
58
|
-
|
59
|
-
self
|
64
|
+
{ failed: failed, succeeded: succeeded, skipped: skipped }
|
60
65
|
end
|
66
|
+
# rubocop:enable Metrics/AbcSize
|
67
|
+
# rubocop:enable Metrics/MethodLength
|
61
68
|
|
62
69
|
def path
|
63
70
|
@path ||= setup_path
|
@@ -66,21 +73,10 @@ module Mangdown
|
|
66
73
|
|
67
74
|
def setup_path(dir = nil)
|
68
75
|
dir ||= DOWNLOAD_DIR
|
69
|
-
path =
|
76
|
+
path = Tools.file_join(dir, name)
|
70
77
|
@path = Tools.relative_or_absolute_path(path)
|
71
78
|
end
|
72
79
|
|
73
|
-
def each(&block)
|
74
|
-
@chapters.each(&block)
|
75
|
-
end
|
76
|
-
|
77
|
-
def load_chapters
|
78
|
-
@chapters += adapter.chapter_list.map do |chapter|
|
79
|
-
chapter[:manga] = name
|
80
|
-
MDHash.new(chapter)
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
80
|
private
|
85
81
|
|
86
82
|
def chapter_indeces(start, stop)
|
data/lib/mangdown/page.rb
CHANGED
@@ -3,21 +3,23 @@
|
|
3
3
|
module Mangdown
|
4
4
|
# Mangdown page
|
5
5
|
class Page
|
6
|
+
extend Forwardable
|
7
|
+
|
6
8
|
include Equality
|
7
9
|
include Logging
|
8
10
|
|
9
|
-
attr_reader :
|
11
|
+
attr_reader :page
|
12
|
+
|
13
|
+
def_delegators :page, :url, :name
|
14
|
+
|
15
|
+
alias uri url
|
10
16
|
|
11
|
-
def initialize(
|
12
|
-
@
|
13
|
-
@chapter = chapter
|
14
|
-
@manga = manga
|
15
|
-
@uri = Addressable::URI.escape(uri)
|
17
|
+
def initialize(page)
|
18
|
+
@page = page
|
16
19
|
end
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
self
|
21
|
+
def chapter
|
22
|
+
@chapter ||= Mangdown.chapter(page.chapter)
|
21
23
|
end
|
22
24
|
|
23
25
|
def path
|
@@ -29,15 +31,16 @@ module Mangdown
|
|
29
31
|
# without file extension if file is not found. File extensions
|
30
32
|
# are appended only after the file has been downloaded.
|
31
33
|
def setup_path(dir = nil)
|
32
|
-
dir ||=
|
34
|
+
dir ||= chapter.path
|
33
35
|
dir = Tools.valid_path_name(dir)
|
36
|
+
name = self.name.tr('/', '')
|
34
37
|
file = Dir.entries(dir).find { |f| f[name] } if Dir.exist?(dir)
|
35
|
-
path =
|
38
|
+
path = Tools.file_join(dir, file || name)
|
36
39
|
@path = Tools.relative_or_absolute_path(path)
|
37
40
|
end
|
38
41
|
|
39
|
-
#
|
40
|
-
def download_to(dir = Dir.pwd, force_download: false)
|
42
|
+
# rubocop:disable Metrics/MethodLength
|
43
|
+
def download_to(dir = Dir.pwd, opts = { force_download: false })
|
41
44
|
delete_files!(dir) if opts[:force_download]
|
42
45
|
|
43
46
|
return if file_exist?(dir)
|
@@ -56,6 +59,7 @@ module Mangdown
|
|
56
59
|
backtrace: error.backtrace
|
57
60
|
}.to_s)
|
58
61
|
end
|
62
|
+
# rubocop:enable Metrics/MethodLength
|
59
63
|
|
60
64
|
def append_file_data(_dir, data)
|
61
65
|
File.open(to_path, 'ab') { |file| file.write(data) }
|
data/lib/mangdown/support/cbz.rb
CHANGED
@@ -29,10 +29,9 @@ module Mangdown
|
|
29
29
|
|
30
30
|
::Zip::File.open(zip_filename, ::Zip::File::CREATE) do |zip|
|
31
31
|
file_matcher = File.join(dir, '**', '**')
|
32
|
-
dir << '/'
|
33
32
|
|
34
33
|
Dir.glob(file_matcher).each do |file|
|
35
|
-
filename = file.sub(dir, '')
|
34
|
+
filename = file.sub("#{dir}/", '')
|
36
35
|
zip.add(filename, file)
|
37
36
|
end
|
38
37
|
end
|