mangdown 0.12.2 → 0.13.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a0ea88db18ac42922a837cb3ed76307d35af9bea
4
- data.tar.gz: c9594ac2a9dba91e307bda03ea3f3630a265591f
3
+ metadata.gz: 0d85a1d5f0bf974970fcc26e817583bfcf16226b
4
+ data.tar.gz: 9b8108fd038b01dd78eda987753c38a4e21c0f94
5
5
  SHA512:
6
- metadata.gz: c4d252007f729afbff7a8d6da1257feec608da2db20fdc7940cfa2f6f875b2e4766f83022dd2845b7a8925be09ae0c043e5ba74cad4edaf369e9392e65363531
7
- data.tar.gz: 528ec01731d20658013268171ea7c168235f0f8572a5fb3948e1c5bc52648a3151b4b8ba2a72feefd4909dde55b3dec2574fb8a8e707b00762b24936dc0e5491
6
+ metadata.gz: c61a0df176b08ed90f5f4a56a8215aa027af64a2f3ed89a7ae722c5cf8d7b32e005b2d8c4851b7ba23abfae80506651e8459b8ee2b66d4c761572cafc6406034
7
+ data.tar.gz: 638112e648008bde76e405c5309b19223cde0a9d684ee4827cfd0901b4170ca723edabab0374884799ef937f4b2e429144a30b7dcc4728f4a78ce999a0100608
@@ -4,7 +4,11 @@ require 'yaml'
4
4
  require 'zip'
5
5
  require 'filemagic'
6
6
 
7
- require_relative 'mangdown/mangdown'
7
+ module Mangdown
8
+ ADAPTERS = []
9
+
10
+ DOWNLOAD_DIR ||= Dir.home + '/manga'
11
+ end
8
12
 
9
13
  require_relative 'mangdown/adapter'
10
14
  adapters = "#{File.expand_path('../mangdown/adapter', __FILE__)}/*.rb"
@@ -12,18 +16,16 @@ Dir[adapters].each do |f|
12
16
  require_relative f
13
17
  end
14
18
 
19
+ require_relative 'mangdown/equality'
15
20
  require_relative 'mangdown/tools'
16
21
  require_relative 'mangdown/properties'
17
22
  require_relative 'mangdown/uri'
18
23
  require_relative 'mangdown/page'
19
24
  require_relative 'mangdown/chapter'
20
25
  require_relative 'mangdown/manga'
21
- require_relative 'mangdown/popular'
22
26
  require_relative 'mangdown/manga_list.rb'
23
27
  require_relative 'mangdown/cbz'
24
28
  require_relative 'mangdown/commands'
25
29
  require_relative 'mangdown/mangdown_hash'
26
30
 
27
- if $0 == __FILE__
28
- puts '*** Use "M.help" for commands ***'
29
- end
31
+
@@ -3,22 +3,43 @@ module Mangdown
3
3
  class Base
4
4
 
5
5
  attr_reader :root
6
- def initialize(uri, doc)
7
- @uri, @doc = uri, doc
8
- #@root = ''
9
- #@manga_list_css = ''
10
- #@chapter_list_css = ''
11
- #@manga_name_css = ''
12
- #@manga_list_uri = ''
13
- #@manga_link_prefix = ''
14
- #@reverse_chapters = true || false
15
- #@manga_uri_regex = /.*/i
16
- #@chapter_uri_regex = /.*/i
17
- #@page_uri_regex = /.*/i
6
+ def initialize(uri, doc, name)
7
+ @uri, @doc, @name = uri, doc, name
8
+ #@root = ''
9
+ #@manga_list_css = ''
10
+ #@chapter_list_css = ''
11
+ #@manga_name_css = ''
12
+ #@chapter_name_css = ''
13
+ #@chapter_manga_name_css = ''
14
+ #@chapter_number_css = ''
15
+ #@manga_list_uri = ''
16
+ #@manga_link_prefix = ''
17
+ #@reverse_chapters = true || false
18
+ #@manga_uri_regex = /.*/i
19
+ #@chapter_uri_regex = /.*/i
20
+ #@page_uri_regex = /.*/i
21
+ end
22
+
23
+ def self.type
24
+ name.split('::').last.downcase.to_sym
18
25
  end
19
26
 
20
27
  def type
21
- self.class.to_s.split('::').last.downcase.to_sym
28
+ self.class.type
29
+ end
30
+
31
+ # Override this if you want to use an adapter name for a site that is
32
+ # not matched in the site's url
33
+ # e.g. CoolAdapterName < Adapter::Base
34
+ # def site
35
+ # "mangareader"
36
+ # end
37
+ def self.site
38
+ type.to_s
39
+ end
40
+
41
+ def site
42
+ self.class.site
22
43
  end
23
44
 
24
45
  # Must return true/false if uri represents a manga for adapter
@@ -38,7 +59,36 @@ module Mangdown
38
59
 
39
60
  # Must return a string
40
61
  def manga_name
41
- doc.css(@manga_name_css).text
62
+ if is_manga?
63
+ doc.css(@manga_name_css).text
64
+ elsif is_chapter?
65
+ chapter_manga_name
66
+ end
67
+ end
68
+
69
+ def chapter_name
70
+ if @name
71
+ @name.sub(/\s(\d+)$/) { |num| ' ' + num.to_i.to_s.rjust(5, '0') }
72
+ else
73
+ doc.css(@chapter_name_css).text
74
+ end
75
+ end
76
+
77
+ def chapter_manga_name
78
+ if @name
79
+ @name.slice(/(^.+)\s/, 1)
80
+ else
81
+ doc.css(@chapter_manga_name_css).text
82
+ end
83
+ end
84
+
85
+ def chapter_number
86
+ raise NoMethodError, "Not a chapter" unless is_chapter?
87
+ if @name
88
+ @name.slice(/\d+\z/).to_i
89
+ else
90
+ doc.css(@chapter_number_css).text
91
+ end
42
92
  end
43
93
 
44
94
  # Must return a uri for a page given the arguments
@@ -61,11 +111,12 @@ module Mangdown
61
111
  # [manga_uri, manga_name, adapter_type]
62
112
  # If block given, then the block may alter this array
63
113
  # Only valid mangas should be returned (using is_manga?(uri))
64
- def manga_list
114
+ def collect_manga_list
65
115
  doc.css(@manga_list_css).map { |a|
66
- manga = ["#{@manga_link_prefix}#{a[:href]}",a.text.strip,type]
67
- next(nil) unless is_manga?(manga.first)
68
- block_given? ? yield(manga) : manga
116
+ manga = ["#{@manga_link_prefix}#{a[:href]}", a.text.strip, type]
117
+ if is_manga?(manga.first)
118
+ block_given? ? yield(manga) : manga
119
+ end
69
120
  }.compact
70
121
  end
71
122
 
@@ -75,9 +126,11 @@ module Mangdown
75
126
  # Only valid chapters should be returned (using is_chapter?(uri))
76
127
  def manga_chapters
77
128
  chapters = doc.css(@chapter_list_css).map { |a|
78
- chapter = [(root + a[:href].sub(root, '')),a.text.strip,type]
79
- next(nil) unless is_chapter?(chapter.first)
80
- block_given? ? yield(chapter) : chapter
129
+ link = root + a[:href].sub(root, '')
130
+ chapter = [link, a.text.strip, type]
131
+ if is_chapter?(chapter.first)
132
+ block_given? ? yield(chapter) : chapter
133
+ end
81
134
  }.compact
82
135
  @reverse_chapters ? chapters.reverse : chapters
83
136
  end
@@ -2,21 +2,21 @@ module Mangdown
2
2
  class Mangafox < Adapter::Base
3
3
  Mangdown::ADAPTERS << self
4
4
 
5
- def initialize(uri, doc)
5
+ def initialize(uri, doc, name)
6
6
  super
7
- @manga_list_css = 'div.manga_list li a'
8
- @chapter_list_css = 'a.tips'
9
- @root = 'http://mangafox.me'
7
+ @manga_list_css = 'div.manga_list li a'
8
+ @chapter_list_css = 'a.tips'
9
+ @root = 'http://mangafox.me'
10
10
  @manga_list_uri = "#{@root}/manga"
11
11
  @manga_name_css = "#title h1"
12
- @manga_link_prefix = ''
13
- @reverse_chapters = true
12
+ @manga_link_prefix = ''
13
+ @reverse_chapters = true
14
14
  @manga_uri_regex =
15
15
  /#{@root}\/manga\/[^\/]+?\//i
16
16
  @chapter_uri_regex =
17
17
  /#{@manga_uri_regex}(v\d+\/)?(c\d+\/)(1\.html)/i
18
18
  @page_uri_regex = /.+\.(png|jpg|jpeg)$/i
19
- end
19
+ end
20
20
 
21
21
  def manga_name
22
22
  CGI.unescapeHTML(super.sub(/ Manga/, '').downcase).upcase
@@ -2,21 +2,21 @@ module Mangdown
2
2
  class Mangahere < Adapter::Base
3
3
  Mangdown::ADAPTERS << self
4
4
 
5
- def initialize(uri, doc)
5
+ def initialize(uri, doc, name)
6
6
  super
7
- @root = 'http://www.mangahere.co'
8
- @manga_list_css = 'a.manga_info'
7
+ @root = 'http://www.mangahere.co'
8
+ @manga_list_css = 'a.manga_info'
9
9
  @manga_name_css = 'h1.title'
10
- @chapter_list_css = '.detail_list ul a'
10
+ @chapter_list_css = '.detail_list ul a'
11
11
  @manga_list_uri = "#{@root}/mangalist/"
12
- @manga_link_prefix = ''
13
- @reverse_chapters = true
12
+ @manga_link_prefix = ''
13
+ @reverse_chapters = true
14
14
  @manga_uri_regex =
15
15
  /#{@root}\/manga\/([^\/]+\/)?/i
16
16
  @chapter_uri_regex =
17
17
  /#{@manga_uri_regex}(v\d+\/)?(c\d+\/)(1\.html)?/i
18
18
  @page_uri_regex = /.+\.(png|jpg|jpeg)$/i
19
- end
19
+ end
20
20
 
21
21
  def manga_name
22
22
  CGI.unescapeHTML(super.downcase).upcase
@@ -4,7 +4,7 @@ module Mangdown
4
4
  class Mangapanda < Mangareader
5
5
  Mangdown::ADAPTERS << self
6
6
 
7
- def initialize(uri, doc)
7
+ def initialize(uri, doc, name)
8
8
  @root = 'http://www.mangapanda.com'
9
9
  super
10
10
  end
@@ -2,7 +2,7 @@ module Mangdown
2
2
  class Mangareader < Adapter::Base
3
3
  Mangdown::ADAPTERS << self
4
4
 
5
- def initialize(uri, doc)
5
+ def initialize(uri, doc, name)
6
6
  super
7
7
  @root ||= 'http://www.mangareader.net'
8
8
  @manga_list_css = 'ul.series_alpha li a'
@@ -23,7 +23,8 @@ module Mangdown
23
23
  end
24
24
 
25
25
  def build_page_uri(uri, manga, chapter, page_num)
26
- "#{root}/#{manga.gsub(' ', '-')}/#{chapter}/#{page_num}"
26
+ slug = slug(manga)
27
+ "#{root}/#{slug}/#{chapter}/#{page_num}"
27
28
  end
28
29
 
29
30
  def num_pages
@@ -45,6 +46,10 @@ module Mangdown
45
46
  def page_image
46
47
  doc.css('img')[0]
47
48
  end
49
+
50
+ def slug(string)
51
+ string.gsub(' ', '-').gsub(/[:,]/, '')
52
+ end
48
53
  end
49
54
  end
50
55
 
@@ -0,0 +1,9 @@
1
+ module Mangdown
2
+ module Adapter
3
+ class NoAdapterError < StandardError
4
+ def initialize(site)
5
+ super("Bad Site: No Properties Specified for Site: #{site.inspect}")
6
+ end
7
+ end
8
+ end
9
+ end
@@ -2,30 +2,30 @@ module Mangdown
2
2
  class Wiemanga < Adapter::Base
3
3
  Mangdown::ADAPTERS << self
4
4
 
5
- def initialize(uri, doc)
5
+ def initialize(uri, doc, name)
6
6
  super
7
- @root = 'http://www.wiemanga.com'
7
+ @root = 'http://www.wiemanga.com'
8
8
  @manga_list_uri =
9
9
  "#{@root}/search/?name_sel=contain&author_sel=contain" +
10
10
  "&completed_series=either"
11
11
  @manga_name_css = '.bookmessagebox h1'
12
- @manga_list_css = 'a.resultbookname'
13
- @chapter_list_css =
12
+ @manga_list_css = 'a.resultbookname'
13
+ @chapter_list_css =
14
14
  '.chapterlist tr:not(:first-child) .col1 a'
15
- @manga_link_prefix = ''
16
- @reverse_chapters = true
15
+ @manga_link_prefix = ''
16
+ @reverse_chapters = true
17
17
  @manga_uri_regex = /#{@root}\/manga\/([^\/]+)(\.html)?/i
18
18
  @chapter_uri_regex =
19
19
  /#{@root}\/chapter\/([^\/]+)\/(\d+)(\/|\.html)?/i
20
20
  @page_uri_regex = /.+\.(png|jpg|jpeg)$/i
21
- end
21
+ end
22
22
 
23
23
  def manga_name
24
24
  super.sub(/ Manga$/, "")
25
25
  end
26
26
 
27
27
  def build_page_uri(uri, manga, chapter, page_num)
28
- "#{uri}-#{page_num}.html"
28
+ "#{uri.sub(/\/+$/, '')}-#{page_num}.html"
29
29
  end
30
30
 
31
31
  def num_pages
@@ -4,56 +4,57 @@ module Mangdown
4
4
  extend ::Mangdown::Tools
5
5
 
6
6
  def all(main_dir)
7
- # Make sure all sub dirs are checked
8
- validate_file_or_dir_names(main_dir)
9
- # Make sure all sub dirs have files checked
10
- check_dir(main_dir) { |dir| validate_file_or_dir_names(dir)}
11
- # Create cbz files for all sub dirs
12
- cbz_sub_dirs(main_dir)
7
+ main_dir = String(main_dir)
8
+ # Make sure all sub dirs are checked
9
+ validate_file_or_dir_names(main_dir)
10
+ # Make sure all sub dirs have files checked
11
+ each_dir_or_page(main_dir) { |dir| validate_file_or_dir_names(dir)}
12
+ # Create cbz files for all sub dirs
13
+ cbz_sub_dirs(main_dir)
14
+ end
15
+
16
+ def one(dir)
17
+ dir = String(dir)
18
+ validate_file_or_dir_names(dir)
19
+ cbz_dir(dir)
13
20
  end
14
21
 
15
22
  private
16
23
  def cbz_dir(dir)
24
+ dir = dir.to_s.sub(/\/*$/, "")
25
+
17
26
  zip_file_name = dir + '.cbz'
18
- dir += '/' unless dir[-1] == '/'
27
+ return if File.exist?(zip_file_name)
19
28
 
20
29
  ::Zip::File.open(zip_file_name, ::Zip::File::CREATE) do |zip|
21
- Dir[File.join(dir, '**', '**')].each do |file|
22
- zip.add(file.sub(dir, ''), file)
30
+ file_matcher = File.join(dir, '**', '**')
31
+ dir << "/"
32
+
33
+ Dir.glob(file_matcher).each do |file|
34
+ filename = file.sub(dir, '')
35
+ zip.add(filename, file)
23
36
  end
24
37
  end
25
38
  end
26
39
 
27
40
  def cbz_sub_dirs(dir)
28
- check_dir(dir) do |sub_dir|
41
+ each_dir_or_page(dir) do |sub_dir|
29
42
  cbz_dir(sub_dir)
30
43
  end
31
44
  end
32
45
 
33
- def check_dir(dir)
34
- Dir.glob(dir + '/*').each do |file_name|
35
- #do block on each file name, but skip .cbz files
36
- next if file_name.include?('.cbz')
37
- yield(file_name)
46
+ def each_dir_or_page(dir)
47
+ Dir.glob(dir + '/*').each do |filename|
48
+ next if filename.include?('.cbz')
49
+ yield(filename)
38
50
  end
39
51
  end
40
52
 
41
53
  def validate_file_or_dir_names(dir)
42
- check_dir(dir) do |file_name|
43
- checked_name = check_file_or_dir_name(file_name)
54
+ each_dir_or_page(dir) do |file_name|
55
+ checked_name = Tools.valid_path_name(file_name)
44
56
  File.rename(file_name, checked_name)
45
57
  end
46
58
  end
47
-
48
- def check_file_or_dir_name(name)
49
- # slice the last number in the file or directory name,
50
- # which will be either the page number or the chapter number
51
- num = name.slice(/(\d+)(\.jpg)*\Z/, 1)
52
- return name unless num
53
-
54
- zeros_to_add = (3-num.length) > 0 ? (3-num.length) : 0
55
- num = "0" * zeros_to_add + num
56
- name.sub(/(\d+)(\.jpg)*\Z/, num + '\2')
57
- end
58
59
  end
59
60
  end
@@ -1,24 +1,33 @@
1
1
  module Mangdown
2
- class Chapter
2
+ class Chapter
3
3
 
4
4
  include Equality
5
5
  include Enumerable
6
- attr_reader :name, :uri, :pages, :manga, :chapter
7
6
 
8
- def initialize(name, uri)
7
+ attr_reader :uri, :pages
8
+
9
+ def initialize(uri, name = nil, manga = nil, chapter = nil)
9
10
  # use a valid name
10
- @name = name.sub(/\s(\d+)$/) { |num|
11
- ' ' + num.to_i.to_s.rjust(3, '0')
12
- }
13
- @manga = name.slice(/(^.+)\s/, 1)
14
- @chapter = name.slice(/\d+\z/).to_i
15
- @uri = Mangdown::Uri.new(uri)
16
- @properties = Properties.new(@uri)
17
- @pages = []
11
+ @name = name
12
+ @manga = manga
13
+ @chapter = chapter
14
+ @uri = Mangdown::Uri.new(uri)
15
+ @properties = Properties.new(@uri, nil, nil, name)
16
+
17
+ load_pages
18
+ end
19
+
20
+ def name
21
+ @name ||= @properties.chapter_name
22
+ end
23
+
24
+ def manga
25
+ @manga ||= @properties.manga_name
26
+ end
18
27
 
19
- get_pages
20
- @pages.sort_by! {|page| page.name}
21
- end
28
+ def chapter
29
+ @chapter ||= @properties.chapter_number
30
+ end
22
31
 
23
32
  def inspect
24
33
  "#<#{self.class} @name=#{name} @uri=#{uri} " +
@@ -28,76 +37,97 @@ module Mangdown
28
37
  alias_method :to_s, :inspect
29
38
 
30
39
  # enumerates through pages
31
- def each
32
- block_given? ? @pages.each { |page| yield(page) } : @pages.each
40
+ def each(&block)
41
+ @pages.each(&block)
42
+ end
43
+
44
+ # explicit conversion to chapter
45
+ def to_chapter
46
+ self
47
+ end
48
+
49
+ def to_path
50
+ @path ||= set_path
51
+ end
52
+
53
+ def set_path(dir = nil)
54
+ dir ||= File.join(DOWNLOAD_DIR, manga)
55
+ path = File.join(dir, name)
56
+ path = Tools.valid_path_name(path)
57
+ @path = Tools.relative_or_absolute_path(path)
33
58
  end
34
59
 
35
- # explicit conversion to chapter
36
- def to_chapter
37
- self
38
- end
60
+ def cbz(dir = to_path)
61
+ CBZ.one(dir)
62
+ end
39
63
 
40
- # download all pages in a chapter
41
- def download_to(dir)
42
- dir = Tools.relative_or_absolute_path(dir, @name)
43
- pages = map {|page| page.to_page}
44
- failed = []
64
+ # download all pages in a chapter
65
+ def download_to(dir = nil)
66
+ pages = map(&:to_page)
67
+ failed = []
45
68
  succeeded = []
46
69
 
47
- Dir.mkdir(dir) unless Dir.exists?(dir)
48
- Tools.hydra_streaming(pages) do |stage, page, data=nil|
70
+ setup_download_dir!(dir)
71
+
72
+ Tools.hydra_streaming(pages) do |stage, page, data = nil|
49
73
  case stage
50
74
  when :failed
51
75
  failed << page
52
76
  when :succeeded
53
77
  succeeded << page
54
78
  when :before
55
- path = page.file_path(dir)
56
- !File.exist?(path)
79
+ !page.file_exist?(to_path)
57
80
  when :body
58
- unless failed.include?(page)
59
- path = page.file_path(dir)
60
- File.open(path, 'ab') { |file| file.write(data) }
61
- end
81
+ page.append_file_data(to_path, data) unless failed.include?(page)
62
82
  when :complete
63
- unless failed.include?(page)
64
- path = page.file_path(dir)
65
- FileUtils.mv(path, "#{path}.#{Tools.file_type(path)}")
66
- end
83
+ page.append_file_ext(to_path) unless failed.include?(page)
67
84
  end
68
85
  end
69
- FileUtils.rm_rf(dir) if succeeded.empty?
70
86
 
71
- !succeeded.empty?
72
- end
87
+ FileUtils.rm_r(to_path) if succeeded.empty?
73
88
 
74
- private
75
- # get page objects for all pages in a chapter
76
- def get_pages
77
- pages = (1..@properties.num_pages).map {|num| get_page_hash(num)}
89
+ { failed: failed, succeeded: succeeded }
90
+ end
91
+
92
+ private
93
+ def setup_download_dir!(dir)
94
+ set_path(dir)
95
+ FileUtils.mkdir_p(to_path) unless Dir.exists?(to_path)
96
+ end
78
97
 
98
+ def load_pages
99
+ @pages ||= []
100
+
101
+ fetch_each_page do |page| @pages << page end
102
+ @pages.sort_by!(&:name)
103
+ end
104
+
105
+ # get page objects for all pages in a chapter
106
+ def fetch_each_page
107
+ pages = build_page_hashes
79
108
  Tools.hydra(pages) do |page, body|
80
- @pages << get_page(page.uri, Nokogiri::HTML(body))
109
+ page = get_page(page.uri, Nokogiri::HTML(body))
110
+ yield(page)
81
111
  end
82
112
  end
83
113
 
84
- # get the doc for a given page number
85
- def get_page_hash(num)
86
- uri_str = @properties.build_page_uri(uri, @manga, @chapter, num)
87
-
88
- MDHash.new(
89
- uri: Mangdown::Uri.new(uri_str).downcase, name: num
90
- )
114
+ # get the docs for number of pages
115
+ def build_page_hashes
116
+ (1..@properties.num_pages).map { |num|
117
+ uri_str = @properties.build_page_uri(uri, manga, chapter, num)
118
+ uri = Mangdown::Uri.new(uri_str).downcase
119
+ MDHash.new(uri: uri, name: num, chapter: name, manga: manga)
120
+ }
91
121
  end
92
122
 
93
123
  # get the page name and uri
94
124
  def get_page(uri, doc)
95
125
  properties = Properties.new(uri, nil, doc)
96
- MDHash.new(
97
- uri: properties.page_image_src,
98
- name: properties.page_image_name,
99
- site: properties.type
100
- )
126
+ uri = properties.page_image_src
127
+ page = properties.page_image_name
128
+ site = properties.type
129
+
130
+ MDHash.new(uri: uri, name: page, chapter: name, manga: manga, site: site)
101
131
  end
102
132
  end
103
133
  end