lknovel 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -5,3 +5,5 @@
5
5
  0.0.4: Remove unnecessary require, check if cover image exist in template and
6
6
  crop
7
7
  0.0.5: Fix lots of errors detected by epubcheck
8
+ 0.0.6: Add --chapter-theads/--image-theads cli options, support download a
9
+ whole series
data/README.md CHANGED
@@ -37,10 +37,16 @@ manually using the package manager. For Debian/Ubuntu:
37
37
  ## Usage
38
38
 
39
39
  $ lknovel -h
40
- Usage: lknovel [options] url
40
+ Usage: lknovel [options] URL ...
41
+
42
+ URL can be:
43
+ http://lknovel.lightnovel.cn/main/vollist/?.html
44
+ http://lknovel.lightnovel.cn/main/book/?.html
41
45
 
42
46
  Specific options:
43
47
  -k, --[no-]keep Keep temporary files
48
+ -t, --chapter-theads THREADS Chapter download threads(4)
49
+ -T, --image-theads THREADS Image download threads(5)
44
50
  -q, --[no-]quiet Run quietly
45
51
 
46
52
  Common options:
@@ -1,6 +1,7 @@
1
1
  require 'erb'
2
2
  require 'fileutils'
3
3
  require 'gepub'
4
+ require 'lknovel/series'
4
5
  require 'lknovel/volume'
5
6
  require 'optparse'
6
7
  require 'ostruct'
@@ -11,16 +12,31 @@ module Lknovel
11
12
  def self.parse(args)
12
13
  options = OpenStruct.new
13
14
  options.verbose = true
15
+ options.chapter_theads = 4
16
+ options.image_theads = 5
14
17
  options.keep = false
15
18
 
16
19
  opt_parser = OptionParser.new do |opts|
17
- opts.banner = 'Usage: lknovel [options] url'
20
+ opts.banner = "Usage: lknovel [options] URL ...\n\n"
21
+ opts.banner << "URL can be:\n"
22
+ opts.banner << " http://lknovel.lightnovel.cn/main/vollist/?.html\n"
23
+ opts.banner << " http://lknovel.lightnovel.cn/main/book/?.html\n"
18
24
  opts.separator "\nSpecific options:"
19
25
 
20
26
  opts.on('-k', '--[no-]keep', 'Keep temporary files') do |k|
21
27
  options.keep = k
22
28
  end
23
29
 
30
+ opts.on('-t', '--chapter-theads THREADS', Integer,
31
+ "Chapter download threads(#{options.chapter_theads})") do |ct|
32
+ options.chapter_theads = ct
33
+ end
34
+
35
+ opts.on('-T', '--image-theads THREADS', Integer,
36
+ "Image download threads(#{options.image_theads})") do |it|
37
+ options.image_theads = it
38
+ end
39
+
24
40
  opts.on('-q', '--[no-]quiet', 'Run quietly') do |q|
25
41
  options.verbose = !q
26
42
  end
@@ -54,15 +70,34 @@ module Lknovel
54
70
 
55
71
  def run
56
72
  ARGV.each do |url|
57
- process_volume(url)
73
+ if url.start_with?('http://lknovel.lightnovel.cn/main/book/')
74
+ volume = Volume.new(url)
75
+ process_volume(volume)
76
+ elsif url.start_with?('http://lknovel.lightnovel.cn/main/vollist/')
77
+ series = Series.new(url)
78
+ series.parse
79
+ series.volumes.each do |volume|
80
+ process_volume(volume)
81
+ end
82
+ else
83
+ puts "Unsupported url: #{url}"
84
+ end
58
85
  end
59
86
  end
60
87
 
61
- def process_volume(url)
62
- volume = Volume.new(url)
88
+ def process_volume(volume)
89
+ volume.parse
90
+ if File.exists?("#{volume.path}.epub")
91
+ puts "Skip: #{volume.path}.epub"
92
+ puts
93
+ return
94
+ end
95
+ puts "Start: #{volume.title}"
63
96
 
64
- parallel_verbose(volume.chapters, title: 'Chapters',
65
- verbose: @options.verbose) do |chapter|
97
+ parallel_verbose(volume.chapters,
98
+ title: 'Chapters',
99
+ threads: @options.chapter_theads,
100
+ verbose: @options.verbose) do |chapter|
66
101
  chapter.parse
67
102
  chapter.title
68
103
  end
@@ -79,8 +114,10 @@ module Lknovel
79
114
  end
80
115
  end
81
116
 
82
- parallel_verbose(images, title: 'Images',
83
- verbose: @options.verbose) do |image|
117
+ parallel_verbose(images,
118
+ title: 'Images',
119
+ threads: @options.image_theads,
120
+ verbose: @options.verbose) do |image|
84
121
  image.download
85
122
  image.file
86
123
  end
@@ -119,8 +156,12 @@ module Lknovel
119
156
  contributor volume.illustrator, 'ill'
120
157
 
121
158
  resources(:workdir => volume.path) {
122
- cover_image = File.join(IMAGE_DIR, volume.cover_image)
123
- cover_image cover_image
159
+ if volume.cover_image
160
+ cover_image = File.join(IMAGE_DIR, volume.cover_image)
161
+ cover_image cover_image
162
+ else
163
+ cover_image = nil
164
+ end
124
165
  file \
125
166
  "#{STYLESHEET_DIR}/default.css" => "#{STYLESHEET_PATH}/default.css"
126
167
  images = Dir.glob("#{IMAGE_DIR}/*").select {|x| x != cover_image}
@@ -138,6 +179,7 @@ module Lknovel
138
179
  builder.generate_epub("#{volume.path}.epub")
139
180
  FileUtils.rm_r volume.path unless @options.keep
140
181
  puts "Finish: #{volume.path}.epub"
182
+ puts
141
183
 
142
184
  end
143
185
 
@@ -17,6 +17,7 @@ img {
17
17
 
18
18
  ol li {
19
19
  padding-top: 15px;
20
+ list-style-type: none;
20
21
  }
21
22
 
22
23
  .page-break {
@@ -14,9 +14,9 @@ module Lknovel
14
14
  attr_reader :url, :title, :content
15
15
 
16
16
  def initialize(url, options = {})
17
- @options = {:title => nil}.merge(options)
17
+ options = {:title => nil}.merge(options)
18
18
  @url = url
19
- @title = @options[:title]
19
+ @title = options[:title]
20
20
  end
21
21
 
22
22
  def parse
@@ -1,5 +1,5 @@
1
1
  module Lknovel
2
- VERSION = "0.0.5"
2
+ VERSION = "0.0.6"
3
3
  MODULE_PATH = File.expand_path('..', __FILE__)
4
4
  TEMPLATE_PATH = File.join(MODULE_PATH, 'templates')
5
5
  STYLESHEET_PATH = File.join(MODULE_PATH, 'assets', 'stylesheets')
@@ -0,0 +1,27 @@
1
+ # encoding: utf-8
2
+ require 'lknovel/utils'
3
+ require 'lknovel/volume'
4
+ require 'nokogiri'
5
+ require 'open-uri'
6
+
7
+ module Lknovel
8
+ class Series
9
+ attr_reader :volumes
10
+
11
+ def initialize(url)
12
+ @url = url
13
+ end
14
+
15
+ def parse
16
+ page = retryable do
17
+ Nokogiri::HTML(open(@url))
18
+ end
19
+
20
+ @volumes = page.css('dl dd h2.ft-24 strong a').map do |x|
21
+ volume_title = x.text.split("\r\n")[-1].strip
22
+ volume_url = x['href']
23
+ Volume.new(volume_url, title: volume_title)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -33,7 +33,8 @@ def parallel_verbose(items, options = {}, &block)
33
33
  msg = "\r#{opts[:title]}: 0/#{items.size} ..."
34
34
  STDERR.write msg
35
35
  end
36
- Parallel.each_with_index(items, :in_threads => 5) do |item, index|
36
+ Parallel.each_with_index(items,
37
+ :in_threads => opts[:threads]) do |item, index|
37
38
  extra_msg = block.call(item, index)
38
39
  if opts[:verbose]
39
40
  # get previous console output length, aware of wide chars
@@ -14,9 +14,10 @@ module Lknovel
14
14
 
15
15
  attr_accessor :cover_image
16
16
 
17
- def initialize(url)
17
+ def initialize(url, options = {})
18
+ options = {:title => nil}.merge(options)
18
19
  @url = url
19
- parse
20
+ @title = options[:title]
20
21
  end
21
22
 
22
23
  def parse
@@ -1,10 +1,11 @@
1
- begin
1
+ CI = !!ENV['TRAVIS']
2
+
3
+ if CI
2
4
  require 'coveralls'
3
5
  Coveralls.wear!
4
- rescue LoadError
5
6
  end
6
7
 
7
8
  $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
8
9
 
9
10
  require 'minitest/autorun'
10
- require 'pry-rescue/minitest'
11
+ require 'pry-rescue/minitest' unless CI
@@ -13,12 +13,9 @@ describe Lknovel::Image do
13
13
  image.file.must_equal '20120808202600_62961.jpg'
14
14
  end
15
15
 
16
- it 'download' do
16
+ it 'download and crop' do
17
17
  image.download(TMP)
18
18
  File.exists?(File.join(TMP, image.file)).must_equal true
19
- end
20
-
21
- it 'crop' do
22
19
  cover_image = File.join(TMP, 'cover.jpg')
23
20
  cropped = image.crop(cover_image, '52%x100%+0+0', :dir => TMP) { |w, h| w > h * 1.5 }
24
21
  cropped.must_equal true
@@ -0,0 +1,15 @@
1
+ # encoding: utf-8
2
+ require 'minitest_helper'
3
+ require 'lknovel/series'
4
+
5
+ describe Lknovel::Series do
6
+
7
+ series = Lknovel::Series.new('http://lknovel.lightnovel.cn/main/vollist/615.html')
8
+ series.parse
9
+
10
+ it 'volume[0]' do
11
+ volume = series.volumes[0]
12
+ volume.url.must_equal 'http://lknovel.lightnovel.cn/main/book/2123.html'
13
+ end
14
+
15
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lknovel
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.6
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2014-03-20 00:00:00.000000000 Z
12
+ date: 2014-03-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -145,6 +145,7 @@ files:
145
145
  - lib/lknovel/chapter.rb
146
146
  - lib/lknovel/image.rb
147
147
  - lib/lknovel/meta.rb
148
+ - lib/lknovel/series.rb
148
149
  - lib/lknovel/templates/chapter.html.erb
149
150
  - lib/lknovel/templates/front.html.erb
150
151
  - lib/lknovel/utils.rb
@@ -154,6 +155,7 @@ files:
154
155
  - test/test_lknovel.rb
155
156
  - test/test_lknovel_chapter.rb
156
157
  - test/test_lknovel_image.rb
158
+ - test/test_lknovel_series.rb
157
159
  - test/test_lknovel_volume.rb
158
160
  homepage: https://github.com/azuwis/ruby-lknovel
159
161
  licenses:
@@ -185,5 +187,6 @@ test_files:
185
187
  - test/test_lknovel.rb
186
188
  - test/test_lknovel_chapter.rb
187
189
  - test/test_lknovel_image.rb
190
+ - test/test_lknovel_series.rb
188
191
  - test/test_lknovel_volume.rb
189
192
  has_rdoc: