lib/command/diff.rb in narou-1.5.11 vs lib/command/diff.rb in narou-1.6.0

- old
+ new

@@ -7,45 +7,50 @@ require "tempfile" require "open3" require_relative "../downloader" require_relative "../database" require_relative "../template" -require_relative "../globalsetting" +require_relative "../inventory" require_relative "../helper" module Command class Diff < CommandBase - def oneline_help - "アップデートされた小説の変更点を表示します" + def self.oneline_help + "更新された小説の差分を表示します" end def initialize - super("[<target>] [options ...]") + super("[<target>] [options]") @opt.separator <<-EOS - ・指定した小説のアップデート前後の変更部分を setting コマンドで指定した difftool で表示します。 - ・引数を指定しなかった場合は直前に更新した小説の変更点を表示します。 + ・指定した小説の更新前後の変更点の差分を表示します。 + ・対象小説を指定しなかった場合は直前に更新した小説の差分を表示します。 + ・もし自分の好きな差分表示プログラムを使いたい場合、difftoolを設定して変更することが出来ます(下記参照) - Example: - narou diff # 直前に更新した小説の変更点を表示 + Examples: + narou diff # 直前に更新した小説の差分を表示 narou diff 6 narou diff 6 -n 2 # 最新から2番目の差分との比較 narou diff 6 -2 # -n 2 の省略した記述方法 - narou diff 6 2013.02.21@01;39;46 # 差分を直接指定 + narou diff 6 2013.02.21@01.39.46 # 差分を直接指定 + narou diff 6 -l # 過去にどの話数の差分があるのかを確認 - # 差分表示用プログラムの指定 - narou setting difftool="C:\\Program Files\\WinMerge\\WinMergeU.exe" + # 自分の好きな差分表示プログラムを使う場合 + narou s difftool="C:\\Program Files\\WinMerge\\WinMergeU.exe" + narou s difftool=colordiff # コマンドラインツールを指定したり + # Narou.rbオリジナルの差分表示に戻す場合は設定を削除する + narou s difftool= # difftoolに渡す引数(指定しなければ単純に新旧ファイルを引数に呼び出す) - # 特殊な変数 %NEW : DLした最新データの差分用ファイルパス + # 特殊な変数 %NEW : 最新データの差分用ファイルパス # %OLD : 古い方の差分用ファイルパス - narou setting difftool.arg='-e -x -ub -dl "NEW" -dr "OLD" %NEW %OLD' + narou s difftool.arg='-e -x -ub -dl "OLD" -dr "NEW" %OLD %NEW' + narou s difftool.arg="-u %OLD %NEW" Options: EOS - @options["number"] = 1 @opt.on("-n NUM", "--number", "比較する差分を遡って指定する。最新のアップデートと直前のデータを比較するなら-n 1、2個前のアップデートなら-n 2。(デフォルトは-n 1)", Integer) { |number| @options["number"] = number if number > 1 } @opt.on("-l", "--list", "指定した小説の差分一覧を表示する") { @options["list"] = true @@ -70,10 +75,11 @@ end def execute(argv) short_number_option_parse(argv) super + @options["number"] = 1 unless @options["number"] if argv.empty? latest = Database.instance.sort_by_last_update.first return unless latest id = latest["id"] else @@ -85,11 +91,11 @@ return end view_diff_version = argv.shift if view_diff_version if invalid_diff_version_string?(view_diff_version) - error "差分指定の書式が違います(正しい例:2013.02.21@01;39;46)" + error "差分指定の書式が違います(正しい例:2013.02.21@01.39.46)" return end @options["view_diff_version"] = view_diff_version end if @options["list"] @@ -102,20 +108,22 @@ end if @options["all-clean"] clean_all_diff return end - @difftool = GlobalSetting.get["global_setting"]["difftool"] + @difftool = Inventory.load("global_setting", :global)["difftool"] unless @difftool - error "difftool が設定されていません。narou setting で difftool を設定して下さい" + display_diff_on_oneself(id) return + #error "difftool が設定されていません。narou setting で difftool を設定して下さい" + #return end exec_difftool(id) end def invalid_diff_version_string?(str) - str !~ /^\d{4}\.\d{2}\.\d{2}@\d{2};\d{2};\d{2}$/ + str !~ /^\d{4}\.\d{2}\.\d{2}@\d{2}[;.]\d{2}[;.]\d{2}$/ end def clean_diff(id) cache_root_dir = Downloader.get_cache_root_dir(id) print Database.instance.get_data("id", id)["title"] + " の" @@ -135,30 +143,30 @@ path.encode!(Encoding::Windows_31J) end %!"#{path}"! }) begin - res = Open3.capture3(diff_cmd) + res = Helper::AsyncCommand.exec(diff_cmd) rescue Errno::ENOENT => e error e.message exit 1 ensure - temp_paths.each { |tmp| tmp.delete } + temp_paths.map(&:delete) end puts res[0] unless res[0].empty? error res[1] unless res[1].empty? end - def create_difftool_command_string(left, right) - diff_arg = GlobalSetting.get["global_setting"]["difftool.arg"] + def create_difftool_command_string(temp_old_path, temp_new_path) + diff_arg = Inventory.load("global_setting", :global)["difftool.arg"] diff_cmd = %!"#{@difftool}" ! if diff_arg - diff_arg.gsub!("%NEW", left) - diff_arg.gsub!("%OLD", right) + diff_arg.gsub!("%OLD", temp_old_path) + diff_arg.gsub!("%NEW", temp_new_path) diff_cmd += diff_arg else - diff_cmd += [left, right].join(" ") + diff_cmd += [temp_old_path, temp_new_path].join(" ") end diff_cmd end def get_sorted_cache_list(id) @@ -174,11 +182,11 @@ cache_dir = nil unless File.exists?(cache_dir) end else nth = @options["number"] list = get_sorted_cache_list(id) - cache_dir = list[nth - 1] if list + cache_dir = list ? list[nth - 1] : nil end unless cache_dir puts "差分データがありません" return nil end @@ -197,22 +205,32 @@ latest_novel_sections << YAML.load_file(match_latest_path) if File.exists?(match_latest_path) cache_sections << YAML.load_file(path) end novel_info = Database.instance[id] + temp_old = create_temp_by_sections("old", cache_sections, novel_info) + temp_new = create_temp_by_sections("new", latest_novel_sections, novel_info) - sections = latest_novel_sections - temp_new = Tempfile.open(["new", ".txt"]) - temp_new.write(Template.get("diff.txt", binding)) - temp_new.close + [temp_old, temp_new] + end - sections = cache_sections - temp_old = Tempfile.open(["old", ".txt"]) - temp_old.write(Template.get("diff.txt", binding)) - temp_old.close - - [temp_new, temp_old] + def create_temp_by_sections(temp_prefix, sections, novel_info) + html = HTML.new + sections.each do |section| + element = section["element"] + data_type = element.delete("data_type") || "text" + element.each do |text_type, elm_text| + if data_type == "html" + html.string = elm_text + element[text_type] = html.to_aozora + end + end + end + temp = Tempfile.open([temp_prefix, ".txt"]) + temp.write(Template.get("diff.txt", binding)) + temp.close + temp end def display_diff_list(id) cache_list = get_sorted_cache_list(id) print Database.instance.get_data("id", id)["title"] + " の" @@ -242,8 +260,21 @@ cache_root_dir = Downloader.get_cache_root_dir(id) next unless File.exists?(cache_root_dir) FileUtils.remove_entry_secure(cache_root_dir) puts "#{data["title"]} の差分を削除しました" end + end + + # + # diff-lcs を使って自力で差分表示 + # + def display_diff_on_oneself(id) + require_relative "../diffviewer" + temp_paths = create_temp_files(id) or return + title = Database.instance.get_data("id", id)["title"] + puts "#{title} の差分を表示します" + DiffViewer.new(*temp_paths).view + ensure + temp_paths.map(&:delete) if temp_paths end end end