ソースコード
# -*- coding: Windows-31J -*- =begin rdoc =TODOをJSON形式に変換する =end class Todo2Json # TODO区切り文字:| TODO_SEPARATOR = '|' # デイリー区切り文字:■ DAILY_SEPARATOR = '■' # TODO区切り文字数:5 TODO_LENGTH = 5 # task項目位置:0 COLUMN_TODO_TASK = 0 # estimate項目位置:1 COLUMN_TODO_ESTIMATE = 1 # actualResultsTime項目位置:4 COLUMN_TODO_ACTUAL_RESULT_TIME = 4 # date項目位置:0 COLUMN_DAILY_DATE = 0 # 不正なマンスリー:'incorrect input monthly' ERR_MONTHLY = 'incorrect input monthly' =begin rdoc ==一行のTODOをJSON形式に変換する 以下の形式のTODOを タスク|見積|開始時間|終了時間|実績時間 以下の形式のJSONに変換する "todo":{ "task":"タスク", "estimate":"見積", "actualResultsTime":"実績時間" } ===Param todo 1行のTODO ===Return TODOを変換したJSON文字列 ===Contract TODOが正しい書式の場合はJSONに変換して返却する ===Contract TODOが不正な値の場合は空文字を返却する =end def get_todo_json(todo) return '' unless is_correct_todo todo columns = todo.split Todo2Json::TODO_SEPARATOR todo_json =<<"EOS" "todo":{ "task":"#{columns[COLUMN_TODO_TASK]}", "estimate":"#{columns[COLUMN_TODO_ESTIMATE]}", "actualResultsTime":"#{columns[COLUMN_TODO_ACTUAL_RESULT_TIME].chomp}" } EOS return todo_json.chomp end =begin rdoc ==デイリーをJSON形式に変換する 以下の形式のデイリーを 2012/02/08 タスク1|見積1|開始時間1|終了時間1|実績時間1 タスク2|見積2|開始時間2|終了時間2|実績時間2 タスク3|見積3|開始時間3|終了時間3|実績時間3 以下の形式のJSONに変換する {"date":"2012/02/08"}, [ { "todo":{ "task":"タスク1", "estimate":"見積1", "actualResultsTime":"実績時間1" } }, { "todo":{ "task":"タスク2", "estimate":"見積2", "actualResultsTime":"実績時間2" } }, { "todo":{ "task":"タスク3", "estimate":"見積3", "actualResultsTime":"実績時間3" } } ] ===Param daily デイリー ===Return デイリーを変換したJSON文字列 ===Contract デイリーが正しい書式の場合はJSONに変換して返却する ===Contract デイリーが1行しかない場合は不正とし、空文字を返す ===Contract デイリーが2行異常があるが、有効なTODOが1件もない場合は不正とし、空文字を返す =end def get_daily_json(daily) return '' unless is_correct_daily daily lines = daily.lines.to_a # 日付部の設定 daily_json = <<"EOS" {"date":"#{lines[COLUMN_DAILY_DATE].chomp!}"}, [ EOS # TODO部の設定 (1..lines.length-1).each {|num| todo_json = get_todo_json lines[num] daily_json +=<<"EOS" { #{todo_json} }, EOS } # 余分な改行文字とカンマを削除 daily_json = daily_json.chomp!.slice(0,daily_json.size-1) daily_json += "\n]\n" return daily_json end =begin rdoc ==マンスリーをJSON形式に変換する 以下の形式のマンスリーを ■2012/02/08 タスク0208-1|見積0208-1|開始時間0208-1|終了時間0208-1|実績時間0208-1 ■2012/02/09 タスク0209-1|見積0209-1|開始時間0209-1|終了時間0209-1|実績時間0209-1 ■2012/02/10 タスク0210-1|見積0210-1|開始時間0210-1|終了時間0210-1|実績時間0210-1 以下の形式のJSONに変換する [ {"date":"2012/02/08"}, [ { "todo":{ "task":"タスク0208-1", "estimate":"見積0208-1", "actualResultsTime":"実績時間0208-1" } } ] ], [ {"date":"2012/02/09"}, [ { "todo":{ "task":"タスク0209-1", "estimate":"見積0209-1", "actualResultsTime":"実績時間0209-1" } } ] ], [ {"date":"2012/02/10"}, [ { "todo":{ "task":"タスク0210-1", "estimate":"見積0210-1", "actualResultsTime":"実績時間0210-1" } } ] ] ===Param monthly マンスリー ===Return マンスリーを変換したJSON文字列 ===Contract マンスリーが正しい書式の場合はJSONに変換して返却する ===Contract マンスリーが空文字の場合はエラーとする ===Contract マンスリーがnilの場合はエラーとする ===Contract デイリーが1つもない場合はエラーとする ===Contract デイリーの戻り値が空文字だった場合はJSONのハッシュを追加しない ===Contract 全デイリーの戻り値が空文字だった場合はエラーとする =end def get_monthly_json(monthly) raise Todo2Json::ERR_MONTHLY unless is_correct_monthly monthly # 区切り文字を分割してマンスリーからデイリーの配列を取得 days = monthly.split Todo2Json::DAILY_SEPARATOR monthly_json = '' valid_count = 0 # 最初の要素は削除する(■yyyy/mm/ddから始まるため) days.delete_at(0) days.each {|daily| daily_json = get_daily_json daily # 有効なデイリーではなかったら次のデイリーへ next if daily_json.empty? valid_count += 1 daily_json = <<"EOS" [ #{daily_json.chomp} ], EOS monthly_json += daily_json } raise Todo2Json::ERR_MONTHLY if valid_count == 0 # 余分な改行文字とカンマを削除 monthly_json = monthly_json.chomp!.slice(0,monthly_json.size-1) monthly_json = "[#{monthly_json}]" return monthly_json end =begin ==マンスリーファイル出力 指定したファイルに対してマンスリーからjsonへの変換処理を行い、 結果を同フォルダに出力する。 ===Param monthly_file_path マンスリーのファイル名 ===Contract 前提条件:ファイルはtxtのみ(等メソッド以前にチェック済みとする) ===Contract 結果ファイルはマンスリーのtxtと同フォルダに出力する ===Contract 出力ファイル名は入力ファイル名.jsonとする =end def output_json_file(monthly_file_path) monthly_file = open(monthly_file_path) monthly = monthly_file.read monthly_file.close monthly_json = get_monthly_json(monthly) monthly_json_file = open(monthly_file_path.sub('.txt','.json'), "w") monthly_json_file.puts monthly_json monthly_json_file.close end =begin rdoc ==TODOが正しい形式か確認する TODOの形式 タスク|見積|開始時間|終了時間|実績時間 ===Param todo 1行のTODO ===Return 正しいTODOならtrue、不正なTODOならfalse ===Contract TODOがnil、空文字以外かつ区切り文字が4つならば正しい書式とする ===Contract TODOがnilなら不正 ===Contract TODOが空文字なら不正 ===Contract TODOの区切り文字数が3以外なら不正 =end private def is_correct_todo(todo) return false if is_empty_nil todo return false unless (todo.split Todo2Json::TODO_SEPARATOR).size == Todo2Json::TODO_LENGTH return true end =begin rdoc ==デイリーが正しい形式か確認する デイリーの形式 日付 タスク|見積|開始時間|終了時間|実績時間 ===Param daily 1日分のTODO ===Return 正しいデイリーならtrue、不正なデイリーならfalse ===Contract デイリーがnil、空文字以外かつ2行以上かつ有効なTODOが1件以上あるならば正しい書式とする。 ===Contract デイリーが空文字なら不正とする ===Contract デイリーがnilなら不正とする ===Contract デイリーが1行しかないなら不正とする ===Contract デイリーに含まれるTODOが1件以上あるが全て無効の場合は不正とする =end private def is_correct_daily(daily) return false if is_empty_nil daily # デイリー全体が2行以上なければエラー return false unless daily.lines.to_a.length >= 2 lines = daily.lines.to_a # TODO部のチェック (1..lines.length-1).each {|num| return false unless is_correct_todo(lines[num]) } return true end =begin rdoc ==マンスリーが正しい形式か確認する マンスリーの形式 タスク|見積|開始時間|終了時間|実績時間 ===Param monthly 1日分のマンスリー ===Return 正しいマンスリーならtrue、不正なマンスリーならfalse ===Contract マンスリーがnil、空文字以外かつ有効なデイリーが1件以上ある場合は正しい書式とする。 ===Contract マンスリーが空文字なら不正とする ===Contract マンスリーがnilなら不正とする ===Contract マンスリーを区切り文字で分割して要素数が2未満の場合は不正とする =end private def is_correct_monthly(monthly) return false if is_empty_nil monthly days = monthly.split Todo2Json::DAILY_SEPARATOR return false if days.size < 2 return true end =begin rdoc ==emptyかnilを判定 ===Param str emptyかnilを含む可能性のあるオブジェクト ===Return emptyかnilならtrue,それ以外ならfalse ===Contract emptyならtrue ===Contract nilならtrue ===Contract emptyかnil以外ならfalse =end private def is_empty_nil(str) return str.nil? || str.empty? end end