lib/command/list.rb in narou-2.9.5 vs lib/command/list.rb in narou-3.0.0
- old
+ new
@@ -2,25 +2,30 @@
#
# Copyright 2013 whiteleaf. All rights reserved.
#
require_relative "../database"
+require_relative "list/novel_decorator"
module Command
class List < CommandBase
- ANNOTATION_COLOR_TIME_LIMIT = 6 * 60 * 60 # 更新してから何秒まで色を変更するか
+ # 更新してから何秒まで色を変更するか
+ ANNOTATION_COLOR_TIME_LIMIT = 6 * 60 * 60
# MEMO: 0 は昔の小説を凍結したままな場合、novel_type が設定されていないので、
# nil.to_i → 0 という互換性維持のため
NOVEL_TYPE_LABEL = %w(連載 連載 短編)
FILTERS_TYPE = Hash[*%w(series 連載 ss 短編 frozen 凍結 nonfrozen 非凍結)]
+ attr_reader :options
+
def self.oneline_help
"現在管理している小説の一覧を表示します"
end
+ # rubocop:disable Metrics/MethodLength
def initialize
super("[<limit>] [options]")
@opt.separator <<-EOS
・現在管理している小説の一覧を表示します
@@ -79,11 +84,11 @@
@opt.on("-a", "--author", "作者名も表示する") {
@options["author"] = true
}
@opt.on("-f", "--filter VAL", String,
"表示を絞るためのフィルター。スペース区切りで複数可\n" \
- "#{' '*25}#{filter_type_help}") { |filter|
+ "#{' ' * 25}#{filter_type_help}") { |filter|
@options["filters"] = filter.downcase.split
}
@opt.on("-g", "--grep VAL", String,
"指定された文字列でリストを検索する") { |search|
@options["grep"] = search.split
@@ -117,11 +122,11 @@
def test_filter(filters, novel_type, frozen)
apply_sum = filters.inject(0) do |sum, item|
apply = case item
when "series"
- novel_type == 0 && novel_type == 1
+ novel_type == 0 || novel_type == 1
when "ss"
novel_type == 2
when "frozen"
frozen
when "nonfrozen"
@@ -136,30 +141,37 @@
apply_sum == filters.count
end
def header
[
- " ID ",
- @options["general-lastup"] ? " 掲載日 " : " 更新日 ",
- @options["kind"] ? "種別" : nil,
- @options["author"] ? "作者名" : nil,
- @options["site"] ? "サイト名" : nil,
- " タイトル"
+ " ID ",
+ @options["general-lastup"] ? " 掲載日 " : " 更新日 ",
+ @options["kind"] ? "種別" : nil,
+ @options["author"] ? "作者名" : nil,
+ @options["site"] ? "サイト名" : nil,
+ " タイトル"
].compact.join(" | ")
end
def view_date_type
- @options["general-lastup"] ? "general_lastup" : "last_update"
+ @_view_data_type ||= @options["general-lastup"] ? "general_lastup" : "last_update"
end
- def output_list(novels)
- now = Time.now
- today = now.strftime("%y/%m/%d")
+ def now
+ @now ||= Time.now
+ end
+
+ def output_list(novels, limit)
+ took_lines = Hash[decorate_lines(novels).take(limit)]
+ output_lines(took_lines)
+ end
+
+ def decorate_lines(novels)
filters = @options["filters"] || []
selected_lines = {}
- view_date_type_key = view_date_type
novels.each do |novel|
+ novel_decorator = NovelDecorator.new(novel, self)
novel_type = novel["novel_type"].to_i
id = novel["id"]
frozen = Narou.novel_frozen?(id)
unless filters.empty?
@@ -167,82 +179,56 @@
end
if @options["tags"]
next unless valid_tags?(novel, @options["tags"])
end
- disp_id = ((frozen ? "*" : "") + id.to_s).rjust(4)
- disp_id = disp_id.sub("*", "<bold><cyan>*</cyan></bold>") if frozen
- tags = novel["tags"] || []
- selected_lines[id] = [
- disp_id,
- novel[view_date_type_key].strftime("%y/%m/%d").tap { |s|
- new_arrivals_date = novel["new_arrivals_date"]
- last_update = novel["last_update"]
- if new_arrivals_date && new_arrivals_date >= last_update \
- && new_arrivals_date + ANNOTATION_COLOR_TIME_LIMIT >= now
- # 新着表示色
- s.replace "<bold><magenta>#{s}</magenta></bold>"
- elsif last_update + ANNOTATION_COLOR_TIME_LIMIT >= now
- # 更新だけあった色
- s.replace "<bold><green>#{s}</green></bold>"
- end
- },
- @options["kind"] ? NOVEL_TYPE_LABEL[novel_type] : nil,
- @options["author"] ? novel["author"].escape : nil,
- @options["site"] ? novel["sitename"].escape : nil,
- novel["title"].escape + (!@options["kind"] && novel_type == 2 ?
- " <bold><black>(#{NOVEL_TYPE_LABEL[novel_type]})</black></bold>" :
- "") +
- (tags.include?("end") ? " <bold><black>(完結)</black></bold>" : "") +
- (tags.include?("404") ? " <bold><black>(削除)</black></bold>" : ""),
- @options["url"] ? novel["toc_url"].escape : nil,
- @options["tags"] || @options["all-tags"] ?
- tags.empty? ? nil : tags.map{ |tag|
- color = Tag.get_color(tag)
- "<bold><#{color}>#{tag.escape}</#{color}></bold>"
- }.join(",") : nil,
- ].compact.join(" | ")
+ selected_lines[id] = novel_decorator.decorate_line
end
- if @options["grep"]
- @options["grep"].each do |search_word|
- selected_lines.keep_if { |_, line|
- if search_word =~ /^-(.+)/
- # NOT検索
- !line.include?($1)
- else
- line.include?(search_word)
- end
- }
- end
+ grep(selected_lines)
+ end
+
+ def grep(selected_lines)
+ return selected_lines unless @options["grep"]
+ @options["grep"].each do |search_word|
+ selected_lines.keep_if { |_, line|
+ if search_word =~ /^-(.+)/
+ # NOT検索
+ !line.include?($1)
+ else
+ line.include?(search_word)
+ end
+ }
end
+ selected_lines
+ end
+
+ def output_lines(took_lines)
if STDOUT.tty?
puts header
- puts selected_lines.values.join("\n").termcolor
+ puts took_lines.values.join("\n").termcolor
+ elsif @options["echo"]
+ # pipeにそのまま出力するときはansicolorコードが邪魔なので削除
+ puts header
+ puts TermColorLight.strip_tag(took_lines.values.join("\n"))
else
- if @options["echo"]
- # pipeにそのまま出力するときはansicolorコードが邪魔なので削除
- puts header
- puts TermColorLight.strip_tag(selected_lines.values.join("\n"))
- else
- # pipeに接続するときはIDを渡す
- puts selected_lines.keys.join(" ")
- end
+ # pipeに接続するときはIDを渡す
+ puts took_lines.keys.join(" ")
end
end
def execute(argv)
super
database_values = Database.instance.get_object.values
- if !argv.empty? && argv.first =~ /^\d+$/
- num = argv.first.to_i
- else
- num = database_values.size
- end
+ limit =
+ if !argv.empty? && argv.first =~ /^\d+$/
+ argv.first.to_i
+ else
+ database_values.size
+ end
if @options["latest"]
database_values = Database.instance.sort_by(view_date_type)
end
database_values.reverse! if @options["reverse"]
- novels = database_values[0, num]
- output_list(novels)
+ output_list(database_values, limit)
end
end
end