lib/md2site/setup.rb in md2site-0.1.2 vs lib/md2site/setup.rb in md2site-0.1.4
- old
+ new
@@ -18,32 +18,34 @@
require "md2site/statusfile"
require "md2site/listfile"
#
# 初期化
- # @param env [Env] Envクラスのメソッド
+ #
+ # @param env [Env] 環境クラスのメソッド
# @param mes [Messagex] Messagexクラスのインスタンス
def initialize(env, mes)
@env = env
@mes = mes
- @category = @env.category
- @category_x = @env.category_x
+ @category_target = @env.category_target
absolute_path_status_file = env.conf_hs["ABSOLUTE_PATH_STATUS_FILE"]
@url = @env.conf_hs["URL"]
@res = {}
@mes.add_exitcode("EXIT_CODE_BY_EXCEPTION")
@mes.add_exitcode("EXIT_CODE_EXECUTE_SETUP_BEFORE_UPDATE_HTMLFILES")
@mes.add_exitcode("EXIT_CODE_CANNOT_FIND_DEST_DIR")
@mes.add_exitcode("EXIT_CODE_CANNOT_CONVERT_FROM_HTML_TO_MD")
@mes.add_exitcode("EXIT_CODE_PANDOC_EXIT_ABNORMALLY")
- @status_file = StatusFile.new(absolute_path_status_file, @url, @mes)
+ @status_file = StatusFile.new(absolute_path_status_file, @env.absolutepath_root, @url, @mes)
end
#
# サブコマンド実行
+ #
# @param option [String] サブコマンドのオプション
+ # @return [void]
def execute_subcommand(option)
case option.name
when "contentUpdate"
update_htmlfiles
when "zcontents"
@@ -65,10 +67,11 @@
private
#
# リモートサイトのファイル取得
+ #
# @param url [String] 取得先URL
# @return [Array] 第0要素:Datetime 第1要素:UNIXタイム 第2要素:HTTPボディ
def get_remote_file(url)
connection = Faraday.new(url) do |conn|
conn.use(FaradayMiddleware::FollowRedirects)
@@ -80,10 +83,11 @@
[datetime_str, datetime_unix_time, res.body]
end
#
# HTTPヘッダの指定フィールドの値を文字列とUNITタイムで取得する
+ #
# @param headers [Hash] HTTPヘッダを表すハッシュ
# @param key [String] HTTPヘッダのフィールドを指定するキー
# @return [Array] 第0要素: 指定フィールドの値(String) 第1要素: 指定フィールドの値(UNIXタイム)
def get_header_value_of_datetime(headers, key)
@res[key] ||= Regexp.compile(Regexp.escape(key))
@@ -111,26 +115,29 @@
[s, unixtime]
end
#
# HTTPヘッダのlast-modifiedフィールドの値を文字列とUNITタイムで取得
+ #
# @param headers [Hash] HTTPヘッダを表すハッシュ
# @return [Array] 第0要素: 指定フィールドの値(String) 第1要素: 指定フィールドの値(UNIXタイム)
def get_modified_in_datetime_from_header(headers)
get_header_value_of_datetime(headers, "last-modified")
end
#
# HTTPヘッダのdateフィールドの値を文字列とUNITタイムで取得
+ #
# @param headers [Hash] HTTPヘッダを表すハッシュ
# @return [Array] 第0要素: 指定フィールドの値(String) 第1要素: 指定フィールドの値(UNIXタイム)
def get_date_in_datetime_from_header(headers)
get_header_value_of_datetime(headers, "date")
end
#
# HTTPヘッダから時刻を表すlast-modifiedフィールドまたはdateフィールのの値を文字列とUNIXタイムで取得
+ #
# @param headers [Hash] HTTPヘッダを表すハッシュ
# @return [Array] 第0要素: 指定フィールドの値(String) 第1要素: 指定フィールドの値(UNIXタイム)
def get_modified_in_datetime_or_date_in_datetime_from_header(headers)
ary = get_modified_in_datetime_from_header(headers)
unless ary.all?
@@ -139,10 +146,11 @@
ary
end
#
# 指定URLのHTTPヘッダから時刻を表すlast-modifiedフィールドまたはdateフィールのの値を文字列とUNIXタイムで取得
+ #
# @param url [String] HTTPヘッダを取得したいURL
# @return [Array] 第0要素: 指定フィールドの値(String) 第1要素: 指定フィールドの値(UNIXタイム)
def get_modified_in_datetime_or_date_in_datetime(url)
connection = Faraday.new(url) do |conn|
conn.use(FaradayMiddleware::FollowRedirects)
@@ -153,27 +161,30 @@
get_modified_in_datetime_or_date_in_datetime_from_header(res.headers)
end
#
# 時刻を"年月日-時分秒"の形式の文字列にする
+ #
# @param datetime [Datetime] Datetimeクラスのインスタンス
# @return [String] "年月日-時分秒"の形式の文字列
def get_datestring(datetime)
datetime.strftime("%Y%m%d-%H%M%S")
end
#
# 現在時刻をDatetimeクラスのインスタンスと文字列にする
+ #
# @return [Array] 第0要素: Datetimeクラスのインスタンス 第1要素: "年月日-時分秒"の形式の文字列
def current_time
datetime = DateTime.now
datetimestr = get_datestring(datetime)
[datetime, datetimestr]
end
#
# 指定サイトでダウンロード指定された全URLのHTTPヘッダの時刻を取得して一覧をファイルに保存
+ #
# @param dir [String] HTTPヘッダ時刻一覧ファイルの保存先ディレクトリ
# @return [Array] 第0要素: Datetimeクラスのインスタンス 第1要素: "年月日-時分秒"の形式の文字列
# @note 一覧を保存するファイルのファイル名はsite-年月日-時分秒.tsvである
def get_remote_file_headers(dir)
_, datetimestr = current_time
@@ -181,27 +192,26 @@
fname = %Q(site-#{datetimestr}.tsv)
fpath = File.join(dir, fname)
@mes.exc_file_write(fpath) do
File.open(fpath, "w") do |ofile|
- @category_x[:category].each do |_k, v|
- v.each do |_k2, v2|
- filename = v2[@env.htmlfile_index]
- next if v2[@env.alias_htmlfile_index]
+ @category_target.each do |_k, v|
+ v[:subTargets].each do |_k2, subtarget|
+ filename = subtarget.htmlfile
+ next unless subtarget.aliashtmlfile && !subtarget.aliashtmlfile&.empty?
if %r{/$}.match?(@url)
file_url = URI.join(@url, filename)
else
file_url = URI.join(@url, "/", filename)
end
ary = get_modified_in_datetime_or_date_in_datetime(file_url)
unless ary.all?
@mes.output_error("Can't find last-modified header from #{@url}")
end
- v2.concat(ary)
- ofile.puts(v2.join("\t"))
+ ofile.puts([file_url].join("\t"))
end
end
end
end
@status_file.fname = fname
@@ -210,74 +220,121 @@
@status_file.update
end
#
# 引数で指定したファイルが書込み可能であるように書込み先ディレクトリを作成
+ #
# @param dir [String] ディレクトリ
# @param filename [String] ファイルへのパス(ファイル名のみも可)
- def prepare_new_write_path(dir, filename)
+ def prepare_new_write_path(dir, filename, postfix=nil)
+ if postfix
+ extname = File.extname(filename)
+ basename = File.basename(filename, extname)
+ new_fname = %Q(#{basename}#{postfix}#{extname})
+ else
+ basename = File.basename(filename)
+ new_fname = basename
+ end
+
dirname = File.dirname(filename)
if dirname != "."
dirpath = File.join(dir, dirname)
@mes.exc_make_directory(dirpath) { FileUtils.mkdir_p(dirpath) }
- basename = File.basename(filename)
- fpath = File.join(dirpath, basename)
+ fpath = File.join(dirpath, new_fname)
else
- fpath = File.join(dir, filename)
+ fpath = File.join(dir, new_fname)
end
+
fpath
end
- def get_remote_contents_sub(target_hash, listfile, last_contents_path)
- target_hash.each do |_, target_def|
- filename = target_def[@env.htmlfile_index]
- next if target_def[@env.alias_htmlfile_index]
+ #
+ # 指定サイトでダウンロード指定された全URLのをファイルとして、保存先ディレクトリにダウンロードし、
+ # ダウンロードステータスファイルを更新
+ #
+ # @param subtarget_hash [Hash] サブターゲット名をキーとしてサブターゲットストラクトを値とするハッシュ
+ # @param listfile [Listfile] ダウンロードファイル一覧ファイル
+ # @param last_contents_path [String] ダウンロード保存先ディレクトリ
+ # @return [void]
+ def get_remote_contents_subtargets(subtarget_hash, listfile, last_contents_path)
+ subtarget_hash.each do |_, subtarget_struct|
+ # filename = target_def[@env.htmlfile_index]
+ unless subtarget_struct.htmldir&.empty?
+ filename = File.join(subtarget_struct.htmldir, subtarget_struct.htmlfile)
+ else
+ filename = subtarget_struct.htmlfile
+ end
+ next unless subtarget_struct.aliashtmlfile&.empty?
+ # file_urlが'//'とならないようにする
if %r{/$}.match?(@url)
file_url = URI.join(@url, filename)
else
file_url = URI.join(@url, "/", filename)
end
+ # file_urlをダウンロードする
remote_datetime_str, remote_datetime_unixtime, content = get_remote_file(file_url)
+ # ダウンロードできなかった場合はエラーメッセージを表示して、次のサブターゲットのダウンロードに移る
unless [remote_datetime_str, remote_datetime_unixtime].all?
@mes.output_error("Can't get content from #{file_url}")
listfile.add([filename, remote_datetime_str, remote_datetime_unixtime, nil])
sleep(ACCESS_WAIT_SEC)
next
end
- fpath = prepare_new_write_path(last_contents_path, filename)
+ # ダウンロードした内容をファイルに書き込む
+ fpath = prepare_new_write_path(last_contents_path, filename)
@mes.exc_file_write(fpath) do
File.open(fpath, "w") do |ofile|
if content
ofile.puts(content)
end
end
end
+ # ダウンロードファイル一覧に追加
listfile.add([filename, remote_datetime_str, remote_datetime_unixtime, Digest::MD5.hexdigest(content)])
end
end
+ #
+ # 指定サイトでダウンロード指定された全URLのをファイルとして、指定ディレクトリ下にダウンロードし、
+ # ダウンロードファイル一覧ファイルを作成し、ダウンロードステータスファイルを更新
+ #
+ # @param dir [String] ダウンロードファイルの保存先ディレクトリ
+ # @return [void]
def get_remote_contents(dir)
_, datetimestr = current_time
@mes.output_info("dir=#{dir}")
@mes.output_info("datetimestr=#{datetimestr}")
last_contents_path = File.absolute_path(File.join(dir, datetimestr))
@mes.exc_make_directory(last_contents_path) { FileUtils.mkdir_p(last_contents_path) }
+ # 保存先ディレクトリ内にダウンロードファイル一覧ファイルを作成
lf = ListFile.new(last_contents_path, @mes)
- @category_x[:category].each do |_, target_hash|
- get_remote_contents_sub(target_hash, lf, last_contents_path)
+ @category_target.each do |_, target_struct|
+ # 各ターゲット毎にファイルをダウンロード
+ get_remote_contents_subtargets(target_struct[:subTargets], lf, last_contents_path)
end
lf.close
+
+ # ダウンロードステータスファイルを更新
@status_file.last_contents_path = last_contents_path
@status_file.update
end
+ #
+ # ダウンロード保存先ディレクトリから指定サブターゲットのHTMLファイルをサブターゲットで
+ # 指定されてディレクトリにコピーし、3分割し、中間部分をMarkdown形式に変換する
+ #
+ # @param subtarget [String] サブターゲットストラクト
+ # @param src_fpath [String] コピー元ファイルパス
+ # @return [void]
+ # @note HTMLファイルからMarkdown形式ファイルへの変換にはpandocを利用するため、pandoc
+ # がインストールされていることが前提
def update_htmlfiles_subtarget(subtarget, src_fpath)
dest_fpath = prepare_new_write_path(@env.absolutepath_root, subtarget.filedir.html_input)
unless dest_fpath
dir = File.dirname(subtarget.filedir.html_input)
path = File.join(@env.absolutepath_root, dir)
@@ -302,27 +359,38 @@
in_html = File.join(dir, %Q(1.html))
unless File.exist?(in_html)
@mes.output_fatal("Can't find file(=#{in_html}")
exit(@mes.ec("EXIT_CODE_CANNOT_FIND_FILE"))
end
- out_md = prepare_new_write_path(@env.absolutepath_root, subtarget.filedir.input_md)
- simple_html2md(in_html, out_md)
-
- path = File.join(@env.absolutepath_root, subtarget.workDir)
- @mes.exc_make_directory(subtarget.workDir) { FileUtils.mkdir_p(path) }
+ out_orig_md = prepare_new_write_path(@env.absolutepath_root, subtarget.filedir.input_md, "_orig")
+ simple_html2md(in_html, out_orig_md)
+ out_md = File.join(@env.absolutepath_root, subtarget.filedir.input_md)
+ @mes.exc_file_copy(out_orig_md, out_md) { FileUtils.cp(out_orig_md, out_md) } unless File.exist?(out_md)
end
+ #
+ # ダウンロードステータスファイルを更新ダウンロード保存先ディレクトリから指定サブターゲットのHTMLファイルをサブターゲットで
+ # 指定されてディレクトリにコピーし、3分割し、中間部分をMarkdown形式に変換する
+ #
+ # @return [void]
def update_htmlfiles
+ # 有効なダウンロードステータスファイルが存在しなければexitする
if @status_file.nil? || @status_file.last_contents_path.nil? || @status_file.last_contents_path.empty?
@mes.output_info("@status_file=#{@status_file}")
unless @status_file.nil?
@mes.output_info("@status_file.last_contents_path=#{@status_file.last_contents_path}")
end
exit(@mes.ec("EXIT_CODE_EXECUTE_SETUP_BEFORE_UPDATE_HTMLFILES"))
else
- @category.each do |_name, category_struct|
+ # 全ターゲットの全サブターゲットのうち、エイリアスHTMLファイルが指定されておらず、かつ未ダウンロード
+ # のもののみをダウンロードする
+ @category_target.each do |_name, category_struct|
category_struct.subTargets.each do |_k, v|
+ # エイリアスHTMLファイルが指定されていても、ワークディレクトリは必要なため、ここで作成する
+ path = File.join(@env.absolutepath_root, v.workDir)
+ @mes.exc_make_directory(path) { FileUtils.mkdir_p(path) }
+
next unless v.aliashtmlfile.empty?
filename = v.htmlfile
next if filename.empty?
src_fpath = File.join(@status_file.last_contents_path, filename)
@@ -334,10 +402,18 @@
end
end
end
end
+ #
+ # HTMLファイルをMarkdown形式に変換する
+ #
+ # @param input_htmlfname [String] 変換元HTMLファイル名
+ # @param outputmd [String] 変換したMakrdown形式ファイル名
+ # @return [void]
+ # @note HTMLファイルからMarkdown形式ファイルへの変換にはpandocを利用するため、pandoc
+ # がインストールされていることが前提
def simple_html2md(input_htmlfname, outputmd)
ret = false
_, _, s = Open3.capture3(%Q(pandoc -o #{outputmd} -t markdown #{input_htmlfname}))
if s.exited?
@@ -353,6 +429,6 @@
end
ret
end
end
-end
+end