このブログについて

はてなダイアリーのインポートの件も落ち着いたので、このあたりでこのブログの自己紹介をします。

このブログは「はてなダイアリー」で2004年から15年近く続けていた「児童小銃」というブログの移転先です。id:rna = なんばりょうすけ が書いています。

元々このブログはダイアリー以外のあちこちの場所に書き散らした文章を一か所に集める目的で始めたものです。ブログの名前「rna fragments」*1 も断片的な文章を集めたものという意味でつけた名前です。

はてなダイアリーのサービス終了にあたり、「児童小銃」の移転先をどうするか考えたのですが、このブログにコンテンツをマージして移転先としました。リダイレクト設定もしてあるので、「児童小銃」の記事へのリンクはこちらのブログの記事に転送されるようになっています。

「児童小銃」のテーマは「見えない自由がほしくて/見えない銃を撃ちまくる」(THE BLUE HEARTS『TRAIN TRAIN』)でした。精神の自由のために容赦ない言論を書き綴る、という意味をこめて、ブログのトップにこの歌詞を引用していました。

「児童小銃」はプライベートな日記ではありましたが、社会問題について議論することも多く、トラックバックやコメント等で多くの方々とやりとりをさせていただきました。得るものも失うものもありましたが貴重な体験でした。

移転にあたって、ブログの名前をどうするか少し悩んだのですが、今の自分はもう「見えない銃を撃ちまくる」ような気力も体力もないですし、思考の断片を残すのがせいぜいだろうという思いもあって、「rna fragments」のままにすることにしました。

このブログとは別に、2017年から「Deep Sky Memories」という天文の趣味に特化したブログを始めて、そちらをメインブログにしています。「Deep Sky Memories」の紹介はこちらのエントリを参照してください。

はてなでブログを始めて15年、個人サイトで日記を書いていた頃から数えると22年以上ネットに文章を書き綴る生活を続けてきましたが、ここ10年ほどはつぶやきばかりでまとまった文章を書くことがほとんどなくなりました。

理由は色々あるのですが、一つにはネットでのコミュニケーションが負担になってきたということがあります。議論する際に、立場の違いはあっても前提は共有できている、という期待ができなくなってきたと思います。

また、これは特に東日本大震災原発事故の後からだと思いますが、通じ合える部分をみつけて仲間意識を持つというよりは、通じ合えない部分をみつけて敵対する、という関係が多くなったように思います。

理由のもう一つは、専門家のネット進出です。ネットの黎明期と違って今は様々な分野の専門家が自らネットで情報発信し、議論する時代です。特に若手はデジタルネイティブでネットでの立ち回りも一流です。ネットに強くてちょっと文章が書ける、という程度の素人の出る幕はありません。

もちろん素人の書くものにも意味はあります。同じ事を考える仲間がそこにいる、ということに勇気づけられる人も多いでしょう。でも僕自身がそういう連帯感にあまり興味がない、というか、どうしても違う意見を持ち出した時に生まれる軋轢の方を心配してしまうのです。

そういうわけで、以前のようには続けられませんが、気が向いた時に何か書く場としてこのブログを使おうと思います。

あと、はてなブログ投稿用のコマンドラインツール HatenaBlogWriter のサポート窓口としてもこのブログを使います。

そういうわけでよろしくお願いします。

*1:昨日まで fragments のスペルが間違っていました…

ISBN/ASIN リンクの修正

はてなダイアリーインポート後の「やり残し」の件。

確認中に気付いたのですが、a タグの href 属性値に書いたisbn記法やasin記法もはてなブログでは展開してくれないんですね… これは別途対処しようと思います。
id記法のリンクの修正 & お詫び

これですが、以下のようなスクリプトで対処しました。id記法リンクの修正まで終わったエントリファイルを orig2 ディレクトリにコピーしてから実行します。

#!/usr/bin/env ruby
# coding: utf-8
# HatenaBlogWriter のワーキングディレクトリで実行します。
# orig2 ディレクトリに変換前のエントリファイルをコピーしてから実行します。

ORIG_DIR = "orig2"
TB_SECTION_SEPARATOR = '<!-- trackback -->'

def load_entry_file(filename)
  header = []
  body = []
  tb = []
  File.open(filename) { |file|
    in_header = true
    in_tb = false
    file.each_line(chomp: true) { |line|
      if (line == TB_SECTION_SEPARATOR) then
        in_tb = true
        next
      elsif in_header && /^$/.match(line) then
        in_header = false
        next
      end
      if in_header then
        header.push(line)
      elsif in_tb then
        tb.push(line)
      else
        body.push(line)
      end
    }
  }
  return { :header => header, :body => body, :tb => tb }
end

def dump_entry_file(filename, entry)
  File.open(filename, "w") { |f|
    f.puts entry[:header]
    f.puts ""
    f.puts entry[:body]
    unless entry[:tb].empty? then
      f.puts TB_SECTION_SEPARATOR
      f.puts entry[:tb]
    end
  }
end

def convert_id_links(lines)
  in_super_pre = false
  new_lines = []
  lines.each { |line|
    if in_super_pre then
      new_lines.push(line)
      in_super_pre = false if line.match(/^||<$/)
      next
    end
    if !in_super_pre && line.match(/^>\|\w*\|$/) then
      new_lines.push(line)
      in_super_pre = true
      next
    end
    # href: isbn/asin
    new_line = line.gsub(/href=['"]\[?(isbn|asin):([^\]'"]+)?\]?['"]/i) { |matched|
      type, code = $~.captures
      url = "http://d.hatena.ne.jp/asin/#{code}/hatena-blog-22"
      "href=\"#{url}\""
    }
    new_lines.push(new_line)
  }
  return new_lines
end

def print_diff(src_lines, dst_lines)
  src_lines.each_index { |i|
    if src_lines[i] != dst_lines[i] then
      puts "- #{src_lines[i]}"
      puts "+ #{dst_lines[i]}"
    end
  }
end

check = (ARGV[0] == "check")
Dir.glob("#{ORIG_DIR}/????-??-??_*.txt").sort.each { |src|
  dst = File.basename(src)
  entry = load_entry_file(src)
  body = entry[:body]
  new_body = convert_id_links(entry[:body])
  if (body != new_body) then
    puts "#{src}:"
    print_diff(body, new_body)
    unless check then
      entry[:body] = new_body
      dump_entry_file(dst, entry)
      puts "saved: #{dst}"
    end
  end
}

URL にくっつけてる hatena-blog-22 はアマゾンアソシエイトIDだと思うのですが、ISBN/ASIN 記法を使うとデフォルトで付いてくるので付けてあります。ID持ってる人は自分のIDと差し替えるといいかも。

これではてなダイアリーの移行作業は一通り終わったかな… 例のフラグメント識別子付きリンクの問題は残っていますが、これははてなが対応してくれればこのままでもいいし、一応リンクの指す情報は飛び先にある(探さないといけないけど)ので、そこまで深刻ではないですし。

はてなブログライター v0.9

はてなブログライター v0.9 をリリースしました。

変更点

  • 新しいコマンド hbwdl.rb を追加しました。
    • Web側で追加・更新したエントリをローカルにダウンロードするツールです。
    • 詳細は README-hbwdl.md を参照してください。
  • hbw.rb に fix_data_url サブコマンドを追加しました。
    • 0.9 より前のバージョンの hbw.rb で投稿したエントリの投稿データファィルにエントリのURLの情報を追加するものです。
    • 通常は使用する必要はありません。詳細は README.md を参照してください。

注意事項

  • hbwdl.rb はまだバグがあるかもしれません。エントリのバックアップを取るなどして自衛しつつ使用してください。
  • 一部のエントリ(おそらく特殊な日付のエントリ)は hbwdl.rb ではダウンロードできません。

id記法のリンクの修正 & お詫び

はてなダイアリーのインポートで移行した記事ですが、id記法で記述したはてなダイアリーへのリンクが全滅しています。これははてなダイアリーはてなブログではid記法の仕様が異なるせいです。なんでうまいこと変換してくれないかなーと思いつつ一括で修正してみました。

例によって HatenaBlogWriter (hbw) を使うのが前提です。

はてなダイアリーはてなブログでのid記法の違い

詳しくは今村さんのブログエントリを参照してください。

ここには書かれてなかったと思うのですが、もう一つ違いがあります。

はてなダイアリーでは a タグの href 属性値にid記法を書くとURLに展開してくれるのですが、はてなブログでは展開してくれません。はてなブログで有効な d:id:rna:20190128:p1 のようなid記法で書いてもダメです。

idリンクの置換

以下のようなスクリプトを書きました。要は正規表現置換なのですが、正規表現は苦手科目です… 何度も試行錯誤できるように元のエントリファイルをサブディレクトリにコピーして、それを入力として変換するようにしました。

convert-id-links.rb:

#!/usr/bin/env ruby
# coding: utf-8
# HatenaBlogWriter のワーキングディレクトリで実行します。
# orig ディレクトリに変換前のエントリファイルをコピーしてから実行します。

ORIG_DIR = "orig"
TB_SECTION_SEPARATOR = '<!-- trackback -->'

def load_entry_file(filename)
  header = []
  body = []
  tb = []
  File.open(filename) { |file|
    in_header = true
    in_tb = false
    file.each_line(chomp: true) { |line|
      if (line == TB_SECTION_SEPARATOR) then
        in_tb = true
        next
      elsif in_header && /^$/.match(line) then
        in_header = false
        next
      end
      if in_header then
        header.push(line)
      elsif in_tb then
        tb.push(line)
      else
        body.push(line)
      end
    }
  }
  return { :header => header, :body => body, :tb => tb }
end

def dump_entry_file(filename, entry)
  File.open(filename, "w") { |f|
    f.puts entry[:header]
    f.puts ""
    f.puts entry[:body]
    unless entry[:tb].empty? then
      f.puts TB_SECTION_SEPARATOR
      f.puts entry[:tb]
    end
  }
end

def convert_id_links(lines)
  in_super_pre = false
  new_lines = []
  lines.each { |line|
    if in_super_pre then
      new_lines.push(line)
      in_super_pre = false if line.match(/^||<$/)
      next
    end
    if !in_super_pre && line.match(/^>\|\w*\|$/) then
      new_lines.push(line)
      in_super_pre = true
      next
    end
    # id link
    new_line = line.gsub(/((\[\])|(href=['"]\[?)|[^:]|^)(id:([\w-]+):(\d{8})(:[\w]+|#[\w]+)?)(\[\])?/i) { |matched|
      pre, esc_begin, href, link, id, date, sect, esc_end = $~.captures
      unless (esc_begin && esc_end) || href
        url = "http://d.hatena.ne.jp/#{id}/#{date}"
        if sect then
          sect.gsub!(/^:/, "/")
          url += sect
        end
        "#{pre}<a href=\"#{url}\">#{link}</a>"
      else
        matched
      end
    }
    # href: diary
    new_line = new_line.gsub(/href=['"]\[?(d:)?id:([\w-]+)(:[^\]'"]+)?\]?['"]/i) { |matched|
      service, id ,path = $~.captures
      url = "http://d.hatena.ne.jp/#{id}"
      if path then
        path.scan(/^:((\d{8})$|(\d{8})(:[\w]+|#[\w]+)$)/) { |s,date1,date2,sect|
          if date1 then
            url += "/#{date1}"
          elsif date2 then
            sect.gsub!(/^:/, "/")
            url += "/#{date2}#{sect}"
          end
        }
      end
      "href=\"#{url}\""
    }
    # href: group
    new_line = new_line.gsub(/href=['"]\[?g:([\w-]+)(:id:([\w-]+)(:[^\]'"]+)?)?\]?['"]/i) { |matched|
      group, id_path, id, path = $~.captures
      url = "http://#{group}.g.hatena.ne.jp"
      if id then
        url += "/#{id}"
        if path then
          path.scan(/^:((\d{8})$|(\d{8})(:[\w]+|#[\w]+)$)/) { |s,date1,date2,sect|
            if date1 then
              url += "/#{date1}"
            elsif date2 then
              sect.gsub!(/^:/, "/")
              url += "/#{date2}#{sect}"
            end
          }
        end
      end
      "href=\"#{url}\""
    }
    # href: group keyword
    new_line = new_line.gsub(/href=['"]\[?g:([\w-]+):keyword:([^\]'']+)\]?['"]/i) { |matched|
      group, keyword = $~.captures
      url = "http://#{group}.g.hatena.ne.jp/keyword/#{keyword}"
      "href=\"#{url}\""
    }
    new_lines.push(new_line)
  }
  return new_lines
end

def print_diff(src_lines, dst_lines)
  src_lines.each_index { |i|
    if src_lines[i] != dst_lines[i] then
      puts "- #{src_lines[i]}"
      puts "+ #{dst_lines[i]}"
    end
  }
end

check = (ARGV[0] == "check")
Dir.glob("#{ORIG_DIR}/????-??-??_*.txt").sort.each { |src|
  dst = File.basename(src)
  entry = load_entry_file(src)
  body = entry[:body]
  new_body = convert_id_links(entry[:body])
  if (body != new_body) then
    puts "#{src}:"
    print_diff(body, new_body)
    unless check then
      entry[:body] = new_body
      dump_entry_file(dst, entry)
      puts "saved: #{dst}"
    end
  end
}

引数に check を指定するとエントリファイルを置換せずに置換する部分の差分表示だけして終わります。

hbw のエントリファイルのヘッダ部分を読み飛ばすようにしています。また、トラックバック以降作業後の作業ということで、以前の作業で追加したトラックバック部分も読み飛ばすようにしています。

基本的に自分の書き方でヒットするケースのみに対処しているので、人によってはこのままでは足りないかもしれません。またはてなダイアリーはてなグループ用のリンクにしか対応していません。

結果の確認

正規表現置換は思わぬ置換ミスを引き起こすことがあるので、上のスクリプトを実行後、diff を取って差分を目で一通り確認しました。350件分。2時間半くらいかかりました。

修正の実行

hbw を実行しておしまい。

やり残し

確認中に気付いたのですが、a タグの href 属性値に書いたisbn記法やasin記法もはてなブログでは展開してくれないんですね… これは別途対処しようと思います。

もう一つ、フラグメント識別子で日記内のセクションへリンクしている場合(http://d.hatena.ne.jp/rna/20190128#p1 等)、はてなブログに移行したダイアリーでリンク先のセクションに対応するエントリには飛ばないという問題があります。

これははてなの方に要望を投げているとことろです。対応してもらえるとありがたいのですが、ダメだった場合どうするか… 大抵の場合はURLを http://d.hatena.ne.jp/rna/20190128/p1 に置き換えてしまえばエントリに飛ぶんですが、なぜかそうならないブログもあるのです。

例えば上の記事で挙げた飯田さんのブログがそうです。おそらくダイアリーを日記モードで使っているとそうなるのかなとにらんでいますが、元がどっちモードだったかなんてわからないのでどうしたものか…

お詫び

最後に、今回の作業でまたidコールが飛びまくったかもしれません。もしそうでしたらお詫びします。

一応エントリの再編集では追加分のidにしかコールが飛ばないはずなのですが…

でも AtomPub からの編集でもそうなのか不明ですし、差分の取り方によっては追加分と認識されそうなので、やっぱり飛んでしまったかも…

人によっては10年以上も前のブログからコールが飛んできて不快かと思いますが、リンクはWebの命だと思っているのでリンク切れは極力なくしたいのです。どうかお許しください。

はてなダイアリーからのトラックバックの移行(その4)(完)

昨日の昼頃にはてなダイアリーのインポートが完了し、その後ブックマークの移行設定とリダイレクト設定をしてインポートが完了しました。その後の作業のメモです。

ダイアリーのURLとブログのURLの対応表を作る(続き)

リダイレクトが有効になったので前回作成した make-redirection-table.rb で対応表を作りました。が、2点問題が。まず、この件なんですが、

でも匿名セクションに対応したエントリって対応する元のURLがないんですけどどうしますかね? おそらく日記のURLに対応するURLに何か付け足したURLになると思うのですが。これはリダイレクト設定後要確認ですね。

日記ページのURLのリダイレクト先を確認したところ、匿名セクションに対応するエントリのURLではなく、その日一日分のエントリをまとめたページに飛んでいました。一方日記ページの URL とその日記の匿名セクション由来のエントリの URL との対応関係は以下のようになっていました。

http://d.hatena.ne.jp/はてなID/YYYYMMDD → http://ブログドメイン/entry/YYYYMMDD

make-redirection-table.rb で作った対応表をこのルールに合わせて修正するスクリプトを以下に。

fix-redirection-table.rb:

#!/usr/bin/env ruby
# coding: utf-8

require 'yaml'

redirection_table = YAML.load_file(ARGV[0])

new_table = {}
redirection_table.each { |diary_url, blog_url|
  if /^http:\/\/d.hatena.ne.jp\/[^\/]+\/([0-9]+)$/.match(diary_url) then
    date = $1
    /^(https?:\/\/[^\/]+)\//.match(blog_url)
    blog_url = "#{$1}/entry/#{date}"
  end
  new_table[diary_url] = blog_url
}
YAML.dump(new_table, STDOUT)

さらにリダイレクトの不具合(制限?)で一部のエントリのリダイレクト先が間違っているという問題がありました。

これは機械的に置き換えることができませんし、3件だけなので手動で対応表を修正することで対応しました。

インポートしたエントリを hbw 形式でダウンロード

インポートしたエントリはサーバ上にしか存在しないため、そのままでは HatenaBlogWriter (hbw) で修正できません。

そこで hbw の hbw-downloader ブランチで hbwdl.rb というスクリプトを作りました。これを使います。

hbw のワーキングディレクトリで以下を実行します。ただし、ローカルで修正したエントリファイルが残っている場合は先に更新しておきます。

hbwdl.rb 0

引数は最新から何件までダウンロードするかの指定ですが、0 は全件ダウンロードの指定になります。

ここで2つ問題が出ました。hbwdl.rb は Atom のフィードを取得してエントリを切り出して保存するのですが、フィードに全件含まれていないようなのです。具体的には 1789 年の1件(1件中)、0001 年の13件(15件中)が含まれていませんでした。

また、0001 年の2件は ruby の atomutil での解析に失敗しました。

title:  ping 送信しないテスト(hw.pl 1.0.1)
エントリの解析に失敗しました。: invalid date: "0001-01-01T00:00:00+09:18:59"
---
title:  ping 送信しないテスト(hw.pl 1.0.1+patch)
エントリの解析に失敗しました。: invalid date: "0001-01-02T00:00:00+09:18:59"

ATOM エントリの編集日時を解析するところでエラーになっています。てっきり1970年より前の日付だからダメとか?と思ったら、そうではなくて、"0001-01-02T00:00:00+09:18" だと解析できるようです。単純に iso8601 に準拠していない日付書式で書かれているせいでエラーになるようです。これはスクリプト側での対応は困難ですね…

これらのエントリは1789年の1件を除いて「はてなダイアリーライター」のテスト用の記事ですし、重要度は低いので今回は諦めることにしました。

エントリのURLとエントリファイルの対応表の作成

hbwdl.rb はローカルにないエントリのエントリファイルを新規作成する際、およびリモート側で修正されたエントリのエントリファイルを(ユーザが応答して)更新する際に、data ファイルにエントリのURLを保存します。

これを利用して以下のスクリプトでエントリのURLとエントリファイルの対応表を作成します。これは hbw のワーキングディレクトリで実行します。

make-url-to-entryfile-table.rb

#!/usr/bin/env ruby
# coding: utf-8
# HatenaBlogWriter のワーキングディレクトリで実行します。

require 'yaml'

DATA_DIR = "data"

table = {}
Dir.glob("*.dat", base: DATA_DIR).map() { |data_filename|
  entry_filename = nil
  if /^(.+)\.dat$/.match(data_filename)
    entry_filename = $1
  else
    next
  end
  data = YAML.load_file("#{DATA_DIR}/#{data_filename}")
  if data['url'] then
    table[data['url']] = entry_filename
  end
}
YAML.dump(table, STDOUT)

エントリファイルにトラックバックを追加する

いよいよエントリファイルを修正します。不測の事態に備えてあらかじめ hbw のワーキングディレクトリを丸ごとバックアップしておきます。

トラックバックをどう表示するか考えものですが、とりあえずエントリの末尾に普通に表示します。末尾と言っても注釈記法を使うと注釈の方が後ろになるという問題があるのですが、今回はそこは目をつぶります。JavaScript で DOM いじって表示するとかしないと対処できないので…

以下のスクリプトを使いますが、引数には三つのファイルを渡します。

  1. 抽出したトラックバックデータ
    • get-tb.rb の出力と get-tb-for-anon-section.rb の出力を reject-empty-trackback.rb に入力して得た出力
  2. ダイアリーのURLとブログのURLの対応表
    • make-redirection-table.rb の出力を fix-redirection-table.rb に入力して得た出力(を必要に応じて手動で修正したもの)
  3. エントリのURLとエントリファイルの対応表
    • make-url-to-entryfile-table.rb の出力

append-tb-section.rb:

#!/usr/bin/env ruby
# coding: utf-8
# HatenaBlogWriter のワーキングディレクトリで実行します。

require 'yaml'

TB_SECTION_SEPARATOR = '<!-- trackback -->'

def load_entry_file_body(filename)
  entry_body = []
  File.open(filename) { |file|
    file.each_line(chomp: true) { |line|
      break if (line == TB_SECTION_SEPARATOR)
      entry_body.push(line)
    }
  }
  return entry_body
end

def make_backup_file(filename)
  File.rename(filename, "#{filename}.bak")
end

def print_tb_list(f, tb_list)
  tb_list.each { |tb|
    one_line_tb = tb.gsub(/[\r\n\t ]+/, " ")
    f.puts "- #{one_line_tb}"
  }
end

def print_tb_lists(f, tb_entry)
  if tb_entry['tb'] then
    f.puts '[]トラックバック[]:'
    print_tb_list(f, tb_entry['tb'])
  end
  if tb_entry['idtb'] then
    f.puts '[]idトラックバック[]:'
    print_tb_list(f, tb_entry['idtb'])
  end
end

def print_tb_section(f, tb_entry)
  f.puts '<hr><div class="referer" style="font-size:75%;background-color:#eee;">'
  print_tb_lists(f, tb_entry)
  f.puts '</div>'
end

def print_entry (f, lines, tb_entry)
  lines.each { |line|
    f.puts(line)
  }
  f.puts TB_SECTION_SEPARATOR
  print_tb_section(f, tb_entry)
end

def print_entry_file(filename, tb_entry)
  lines = load_entry_file_body(filename)
  print_entry(STDOUT, lines, tb_entry)
end

def save_entry_file(filename, tb_entry)
  lines = load_entry_file_body(filename)
  make_backup_file(filename)
  File.open(filename, "w") { |f|
    print_entry(f, lines, tb_entry)
  }
end

tb_filename = ARGV[0]
redirection_table_filename = ARGV[1]
entry_file_table_filename = ARGV[2]

blog_urls = YAML.load_file(redirection_table_filename)
entry_files = YAML.load_file(entry_file_table_filename)

File.open(tb_filename) { |tb_file|
  YAML.load_stream(tb_file) { |entries|
    entries.each { |entry|
      diary_url = entry['url']
      blog_url = blog_urls[diary_url]
      unless blog_url
        puts diary_url + ": blog entry not found."
        next
      end
      entry_filename = entry_files[blog_url]
      unless entry_filename
        puts diary_url + ": entry file not found."
        next
      end
      puts diary_url + ": " + entry_filename
      #print_entry_file(entry_filename, entry)
      save_entry_file(entry_filename, entry)
    }
  }
}

修正したエントリのアップロード

ここまできたらいよいよエントリを更新します。hbw-downloader ブランチの hbw.rb でアップロードしますが、まず一度 hbw.rb check で修正されたエントリファイルの件数を確認します。問題なければ引数なしの hbw.rb を実行。

hbw.rb
新規エントリファイルはありません。
修正されたエントリファイルが 1244 件あります。
OK: 2004-06-22_01.txt: エントリを更新しました。
OK: 2014-02-06_01.txt: エントリを更新しました。
OK: 2004-10-21_06.txt: エントリを更新しました。
...

hbw-downloader ブランチの hbw.rb は速度規制(1件毎に1〜1.5秒のウェイト)が入っているのでややゆっくり目ですが黙々とアップロードが進んでいき、30分ほどで無事更新が完了しました。*1

修正されたエントリはこんな感じになりました。

ということで、これでトラックバック移行作業は完了です。

わかりにくい部分も多々ありますが、スクリプトの処理内容が理解できる人だけがわかるような書き方にしています。他人の環境での動作保証はできないのでよく理解した上で自己責任で実行してください。

あと、これは終わってから気付いたんですが、この作業やると、idコールむちゃくちゃ飛びますね…

改めまして、申し訳ありませんでした。

あと、はてなさん、訴えないでくださーい…

librahack 事件みたいなことになったらやだなー…

idコールは回避方法がなさそうなので参考にする人はそのあたりはご覚悟を。

*1:実はエントリファイルの修正が一部しくじっていてスクリプトを直して再実行して、150件更新しなおすことになったので「無事」ではありませんでしたが…

はてなダイアリーインポート後のリダイレクトがうまくいかない記事がある

トラックバック移行作業時に気付いたのですが、はてなダイアリーのインポート後にリダイレクト設定をしても、一部の記事で間違ったURLにリダイレクトされる現象が発生しています。

具体的には2005年2月29日の記事です。

1つ目のリンクは "Entry is not found" と書かれたページ http://rna.hatenadiary.jp/entry/20050229/p1 に飛び、2つ目のリンクは invalid date とだけ表示されるページ http://rna.hatenadiary.jp/entries/2005/02/29 に飛びます。

…はい、2005年はうるう年ではないので、2月29日なんて日付は本来ありません。しかしはてなダイアリーはそのような日付を許容していました。「はてなダイアリーライター」を使って誤って日付を書き間違えた日記を投稿したところ、エラーにならず2月29日の日記ができてしまったのです。

そのような日付の記事はインポートの際にどうなるかというと、ちゃんと漏れなく取り込まれています。が、前日の2月28日のエントリとして取り込まれていました。その結果1つ目のリンクの記事は http://rna.hatenadiary.jp/entry/20050228/p1 になりました。

ところが、2月28日にはセクション名 p1 の記事が既にあり、通常はこれが http://rna.hatenadiary.jp/entry/20050228/p1 になるはずなのですが… エントリが上書きされてしまうのでは?と思ったのですがそうはならず28日の記事は http://rna.hatenadiary.jp/entry/20050228/p1_1 に取り込まれました。

ここでまた問題が発生します。28日の p1 の記事は以下の URL です。

このリンクを辿ると29日の記事に対応する http://rna.hatenadiary.jp/entry/20050228/p1 に飛ばされてしまいます。困りました。

というわけで、本当はこうなって欲しいわけです。

なんとかなりませんかね?と言ってもテーブルベースでリダイレクトしているならともかく、ルールベースで計算したURLにリダイレクトする仕組みだとお手上げですよね…

一応はてなに報告はしておきますが、どうにもならないかもしれません。

お詫び

このトラックバック移行の件ですが、

ひょっとしてこの作業のせいで大量のidコールが飛んだりしてます…?エントリ更新時は差分にidやURLが含まれる場合のみコールが発生するのかなと思ったけどそうでもないのかな…

いや、そうだとしても、エントリ本文内にトラックバックのデータを追記しているので、はてなダイアリーからトラックバックした人にはもれなくidコールが飛んでいるような…

もしそうでしたらお騒がせしてすみませんでした。idコールのことはすっかり忘れていました。。。