ラベル Blogger の投稿を表示しています。 すべての投稿を表示
ラベル Blogger の投稿を表示しています。 すべての投稿を表示

2011/06/30

Blogger API Get Request

Blogger API に対し最初に発行すべき Get Request 先はどこか? についてわかったこと。

gdata-1.1.2 (ruby-lib)を使ってログインしてから

https://www.blogger.com/feeds/default/blogs

に対して Get リクエストすると基本的な情報が返ってきた。
その XML はこのような構成になっており

<xml root>
  <title/>
  <name/>
  <link/>
  <author/>
  <entry>
    <published/>
    <updated/>
    <category/>
    <link/>
  </entry>
</xml root>


こんなような def を用意すると...

def xinfo_link(str)
   # @xr = response.to_xml.root
   # str = "link" or "entry/link"
   @xr.get_elements("#{str}").each{|x|
    m = x.attributes['rel'].to_s.match(/\#(.*?)$/)
    m ? s = m[1] : s = x.attributes['rel']
    print "#{s} => ", x.attributes['href'], "\n"
  }
end

各種 URL を得ることができました。
下記のリンク先(末尾)の内容どおり実際にテンプレート用URLなども用意されておりちょっと驚きました。

また、これまで使用したラベル(category)も全て格納されておりました。
こんなような def を用意すると、

def category
  # @xr = response.to_xml.root
  @xr.get_elements('entry/category').each{|y| print "[", y.attributes['term'], "]\s"}
  print "\n"
end

category 一覧をみることができました。

# Category:
[Music] [get-item-amazon] [OSX] [SnowLeopard] [readbook] [AirMac] [Safari] [Amazon] [Apple] [importdata] [AirPort] [2010-amazon-api-jp] [News] [MacVim] [mdiary]     [mblogger] [Book] [AppleScript] [google] [gem] [essay] [Leopard] [vi] [Blogger] [Perl] [x] [Nuclear] [sleep] [launchd] [Design] [RubyCocoa] [vim] [iTunes] [git]     [RubyUtility] [Ruby] [daybook] [TV] [RubyOSA] [plutil] [macruby]



下記を参考にさせていただきました。

Blogger Developer Group | Google グループ

Blogger Developers Network: Using OACurl to explore Blogger’s API

I'd Rather Hack: Howto Change Blogger Settings with the GData API

2011/06/22

Changed Blogger's feed access

# Blogger API へアクセスする際は https 使用のこと。

Blogger Developers Network: Clarifying recent changes to Blogger’s feed access
Blogger Developers

Developer\'s Guide: Protocol - Blogger APIs - Google Code
Developers Guide

Blogger API - Google Code
Blogger API

# 新しい gdata
gdata-1.1.2.gem - gdata-ruby-util - Version 1.1.2 - Google Data APIs Ruby Utility Library - Google Project Hosting
gdata-ruby-util

2011/03/07

about xblogger

xblogger について。

ターミナル(/Applications/Utilities/Terminal.app/) から
gdata-ruby-util
を使って Blogger に記事を ポスト| ゲット | 削除 | アップデート する為のものです。

Mac OS X 上で作りました。使用する Ruby は 10.6 に搭載されているRuby 1.8.7 (/usr/bin/ruby) です。
# Ruby 1.9.2 用は mblogger

『はじめに』

xblogger は utf-8 で保存されたテキストファイルで 特定の書式に則ったものだけを対象にしています。ものすごく端折って言うと
--control, --category, --title, --content
が明記されたファイルに記事内容を記入する必要があります。サンプルは xblogger/draft.txt です。

--------------------
0) 準備ー設定
--------------------

gdata-ruby-util からgdata-ruby-util をダウンロードし
xblogger/xblogger-config と xblogger/bin/run.rb を編集してください。

% cd /pathto/download/
% gem unpack gdata-1.1.1.gem
%
% cd xblogger
% vim xblogger-config
% vim bin/run.rb
% chmod +x bin/run.rb


gem を使用したい場合は
% gem install gdata
などして gdata に含まれている README を参照の上 bin/run.rb を書き換えてください。私はこの方法を試していません。

自分の BlogID が不明な場合は下記を試してください。
最初に自分の Blogger Profile Page をみにいきます。その URL に含まれている数字が仮に XXXXX だったとします。

% cd xblogger/bin
% ruby get-blogid.rb XXXXX

を実行。

# xblogger-config の xname は任意の文字列を記入してくださいです。アンダーバーやハイフンは含めない方がよいかもしれません。

--------------------
1) 確認ー投稿前
--------------------

# --doc
# 記事を投稿する前にリクエスト対象となる XML Document を確認します。

サンプル xblogger/draft.txt を test.txt にコピーし編集し保存します。

% cd xblogger
% cp draft.txt test.txt
% vim test.txt
% cat test.txt
--control
yes
--category
test,blogger
--title
TestTitle
--content
test post.
second line.


test.txt を指定。

% cd xblogger/bin
% ./run.rb  --doc ../test.txt
CONTROL: yes
TITLE: TestTitle
CATEGORY: test,blogger
# =====
<entry xmlns='http://www.w3.org/2005/Atom'><title type='text'>TestTitle</title><content type='xhtml'><div xmlns='http://www.w3.org/1999/xhtml'><p>test post.<br/>second line.</p></div></content><app:control xmlns:app='http://www.w3.org/2007/app'><app:draft>yes</app:draft></app:control><category term='test' scheme='http://www.blogger.com/atom/ns#'/><category term='blogger' scheme='http://www.blogger.com/atom/ns#'/></entry>


問題があればエラーになりますがエラーとして認識されない場合もあります。

--------------------
2) 投稿(ポスト)
--------------------

# --post
# Blogger へ記事を投稿します。

さきほどのtest.txt を指定し投稿します。

% ./run.rb  --post ../test.txt
CONTROL: yes
TITLE: TestTitle
CATEGORY: test,blogger
# =====
Post Entry
OK? [y/n]

と尋ねられます。n を選択すると何事もなく終了します。y を選択すると記事を投稿します。投稿に成功すると success message が返ってきます。

この時 ファイル test.txt の --control 値が yes になっていたら下書きの記事として投稿します。記事は公開されません。

--control
yes


yes 以外の文字列になっている場合は公開記事として投稿します。記事は公開されます。

--control
ok


記事文章内にリンクを張りたい時は、

--content
あいうえお <a href='http://github.com'>github.com</a> かきくけこ。

のように記入しておくとハイパーリンクになります。html そのままです。
引用の場合は <blockquote>改行+引用文+改行</blockquote>
コードの場合は <pre>改行+コード+改行</pre> で囲むようにしてください。

詳細は % cat xblogger/draft.txt で確認してください。

--------------------
3) 確認ー投稿後
--------------------

# 記事投稿に成功した場合結果ファイルを自動生成します。
# 下書であろうとなかろうと。

xblogger/bin/run.rb は 記事を投稿した場合に限って 指定したディレクトリに一意のファイルを生成します。
指定したディレクトリ とは、xblogger/xblogger-config に自分で入力した任意のパス。
例えば、~/data ディレクトリを指定していた場合、2011/01/01 に投稿した記事は

~/data/2011-01/2011-01-01T00-00-00-xxxxxx.txt

に保存されます。xxxxxx はBlogger が与えた一意の番号です。

生成されたファイルには、Blogger から受け取った情報が保存されています。具体的には edit_id, published date, updated date, url です。
ただし --control によって"下書き"として投稿した場合は --url はありません。

% cat ~/data/2011-01/2011-01-01T00-00-00-xxxxxx.txt
--edit_id
xxxxxxxxxx
--published
2011-01-01T00:00:00.001+09:00
--updated
2011-01-01T00:00:00.001+09:00
--date
2011/01/01 Sat AM 00:00:00
--control
ok
--category
test
--title
test
--url
http://midorex.blogspot.com/2011/01/test.html
--content
...略


--------------------
4) 削除
--------------------

# --del, --delete
# Blogger へ投稿した記事を削除します。
# 下書きとして投稿した記事を指定することもできます。

自動生成されたファイルの path を指定したい場合

% run.rb --delete path

edit_id を指定したい場合

% run.rb --del xxxxxxx


--------------------
5) アップデート
--------------------

# --update
# 既に投稿した記事内容を修正します。

自動生成されたファイルの中から修正したい投稿ファイルを編集しファイルを保存します。
保存したファイルのパスを指定します。

% run.rb --update ~/data/2011-01/2011-01-01T00-00-00-xxxxxx.txt

[y/n] を尋ねられます。y を選択するとアップデートを実行します。完了すると success message を表示します。

run.rb --update は指定したファイル内容を読み込みます。この時ファイルに保存されているはずの --edit_id が 空欄だったり 間違った番号(Blogger が管理していないような番号)であった場合 アップデートは成功しません。また、--title --category --content の内容は修正できますが ひとたび付与された --url などは変更できません。

余談ですが...
Blogger 記事の URL は
記事タイトルに日本語の文字列が含まれていた場合、その月内で何番目の記事かが考慮された URL となり、日本語が含まれていない場合はスペース等を別の文字に置換した文字列が URLに反映されているようです。

--------------------
6) 記事取得
--------------------

# --get
# 月内に投稿された全ての記事の タイトル, 日付, URL, Category, edit_id などを返します。

--get の後になにもなければ現在の年月を指定したことになります。

% ./run.rb --get


2011年2月を指定したい場合。month は 2桁で指定する必要があります。

% ./run.rb --get 2011-02


--------------------
7) HELP
--------------------

% ./run.rb --h

2011/02/23

Customized template.xml

Blogger template.xml (css) をカスタマイズした際の memo。

1)

.body-fauxcolumn-outer .cap-top {
  position: absolute;
  z-index: 1;
  /* Default */
  /* height: 400px;*/
  height: 5px;
  width: 100%;
  background: $(body.background);
  $(body.background.override)
}

最上部フレーム高さとか。

#navbar-iframe {
...

を追加しないで変更した場合どうなるかは試していない。

2)

.content-inner {
  /* Default */
  /* padding: $(content.padding) $(content.padding.horizontal); */
  padding: 0px 20px;
}

content は ブログタイトル, description, 全ての投稿を包括する大枠。

3)

.header-inner .Header .titlewrapper {
  /* Default */
  /* padding: 22px $(header.padding); */
  padding: 5px $(header.padding);
}

ブログタイトル余白。

4)

.main-inner {
  /* Default
  padding-top: $(main.padding.top);
  padding-bottom: $(main.padding.bottom);
  */
  padding-top: 0px;
  padding-bottom: $(main.padding.bottom);
}

main は全投稿記事を包括するパート。(記事フッタ、日付、タイトル含む)
上部余白を減らすとブログタイトルと記事全体の間が狭くなる。

5)

.post-header {
  margin: 0 0 1.5em;
  line-height: 1.6;
  font-size: 90%;
  /* add */
  border-bottom: 1px solid #6ea1bb;
}

投稿タイトルと投稿記事の間の余白。
padding-top: 20px; などの確認を要した。

6)
mobile のあと。
p, pre-code, blockquote 部分。

/*
----------------------------------------------- */

#navbar-iframe {
  height:0px;
  visibility:hidden;
  display:none
}

/* p tag
----------------------------------------------- */
.post-body p {
  margin: 0px;
  padding: 0px;
  font-size: 10.2pt;
  line-height: 1.6em;
  letter-spacing: 2px;
}

/* pre code
----------------------------------------------- */
.post-body pre {
  margin: 7px 0 7px 0px;
  padding: 7px 0 7px 7px;
  color: #6666B3;
  overflow: auto;
  border-bottom: 1px solid #eeeeee;
  border-left: 1px solid #eeeeee;
  background-color: #FCFFFD;
}
.post-body code {
  margin: 0em;
  padding: 0em;
  font-family: Menlo, Monaco, Monospace;
  font-size: 8.7pt;
  line-height: 1.7em;
  letter-spacing: 1.5px;
}

/* brockquote
----------------------------------------------- */
.post-body blockquote {
  margin: 5px 0px 5px 5px;
  padding: 0.8em 0.5em 0.5em 0.8em;
  color: #555;
  background-color: #FBFDFF;
  border-top: 1px solid #dddddd;
  border-right: 1px solid #dddddd;
  border-bottom: 1px solid #dddddd;
  border-left: 1px solid #dddddd;
}
.post-body blockquote p {
  margin: 0px;
  padding: 0px;
  font-family: Optima, Georgia, sans-serif;
  font-size: 9pt;
  line-height: 1.4em;
  letter-spacing: 2px;
  font-style: italic;
}


カラー参照
http://www.w3schools.com/css/css_colornames.asp

2010/06/27

Blogger Preview

 デザイン->HTMLの編集 画面を表示し
何も編集しないで「プレビュー」をクリックすると
about:blank
になってしまった。まっしろけの画面。はっこれは!? なぜだろう。

Safari の設定を変えて(ポップアップ開く、サイト固有のハックを無効にしない、Runawy JavaScript タイマーを無効にしない、クッキーを常に受け入れる)みたが、やはり about:blank になった。

編集して保存はできたのでよかった。

2010/06/23

GoogleCL post file

GoogleCL から

$ google blogger post --draft --title "test-01" post.txt 

で post する場合

Blogger にログインして
設定->フォーマット->改行の変換を[はい]にしておく必要がある。

こうしておかないと改行のない本文になってしまうようだ。

また --title オプションをつけないでファイルの1行目をタイトルにさせた場合、
実際1行目がタイトルになるんだけど本文にも1行目が残ってしまう...ようだ。

2010/06/21

googleCL

Google のコマンドラインツールを使ってみる をよみまして GoogleCL を試してみました。

(~/home 以下にインストールしたので)

% export PATH=$PATH:/Users/foo/path/to/bin  

投稿してみました。
% google blogger post --title "try-googleCL-1" "command line posting." --tags="google,blogger"
成功しました。

削除してみました。

% google blogger delete --title "try-googleCL-1"
Are you SURE you want to delete post "try-googleCL-1"? (y/N): y
ほんとに削除していいのですか?と訊ねられて y を入力すると投稿は削除されました。

下書きで投稿するには、--draft をつければいいらしい

% google blogger post --draft --title "test-try-googleCL" "command line posting." --tags="test,blogger"
ファイルを指定してみる

% google blogger post post.txt

2010/01/06

mblogger

mblogger について

gdata を使用して Ruby で遊びながら Blogger に投稿するためのツールです。

必要なもの
• Ruby 1.9.1
• gdata-ruby-util <http://code.google.com/p/gdata-ruby-util/downloads/list>
• Blogger アカウント

この記事はテストをかねていたりしてます。

[2010-01-07]
自分のBlogID を取得 or 確認するための get-blogid.rb を作りました。

[その他のメモ]
blogの公開時間設定について
2009-07-01 付けで投稿予定が実行されないトラブルがあるとのこと。
たしかにこの頃から、未来の日付をもつ記事を post しても記事公開の予約に反映されなくなった記憶がある。それ以前は未来の日付をもつ記事を post すると指定された時刻に自動的に記事が公開されていた。はず。なので、おそらく仕様が変わったのだろうと思う。

カテゴリーを指定して Get Request を発行する場合のURL (2009-05-17)
参照:
http://code.google.com/intl/ja/apis/blogger/docs/2.0/developers_guide_protocol.html

例:ラベル Fritz か Laurie を得るための URL

http://www.blogger.com/feeds/blogID/posts/default/-/Fritz/Laurie


[2010-03-06]
% cd /path/to/your/dir
% git clone git://github.com/midore/mblogger.git mblogger
% ls
mblogger
% cd mblogger
% ls
README bin lib

% git clone は、TCP PORT 9418
を使用するのでファイアウォールなどを使用している場合は 9418 が出て行けるように設定する必要があります。

[2011-06-28]
get-blogid.rb を削除。

関連する記事
"Blogger"ラベルがついた全ての記事

gdata

いつのまにか新しい gdata がでていた。
gdata-1.1.1
http://code.google.com/p/gdata-ruby-util/downloads/list

memo
gem19 unpack gdata-1.1.1.gem
ruby 1.9.1 で動かす為に最後の2行をコメントにした。lib/gdata.rb

2009/12/28

url for blogger-api

Blogger API 用
日付範囲を指定したURLの生成

line 10:
t に2010/12 が指定された場合、翌月は年も変わるので年に1加算し月にも1加算すると2011/1/1 が得られそこから1秒ひくと2010/12/31の23:59:59
になる。

Time だけ使った場合

  1 require 'time'
  2 
  3 def range_current_month(t=nil, bid)
  4   u = "http://www.blogger.com/feeds/#{bid}/posts/default"
  5   begin
  6     t = Time.parse(t) unless t.nil?
  7   rescue
  8     t = Time.now()
  9   end
 10   t.month == 12 ? x = [t.year+1, 1] : x = [t.year, t.month+1]
 11   min = t.strftime("%Y-%m-%dT00:00:00")
 12   max = (Time.local(x[0], x[1], 1) -1).strftime("%Y-%m-%dT%H:%M:%S")
 13   return u + "?published-min=#{min}" + "&published-max=#{max}"
 14 end
 15 
 16 bloggerid = 'xxxxxxxxxxxx'
 17 t = '2010/12'
 18 p range_current_month(t, bloggerid)
 19 t = '2010/2'
 20 p range_current_month(t, bloggerid)

=>
"http://www.blogger.com/feeds/xxxxxxxxxxxx/posts/default?published-min=2010-12-01T00:00:00&published-max=2010-12-31T23:59:59"
"http://www.blogger.com/feeds/xxxxxxxxxxxx/posts/default?published-min=2010-02-01T00:00:00&published-max=2010-02-28T23:59:59"


Date も使った場合

  1 require 'time'
  2 require 'date'
  3 
  4 def range_current_month(t=nil, bid)
  5   u = "http://www.blogger.com/feeds/#{bid}/posts/default"
  6   begin
  7     t = Time.parse(t) unless t.nil?
  8   rescue
  9     t = Time.now()
 10   end
 11   t.month == 12 ? x = [t.year+1, 1] : x = [t.year, t.month+1]
 12   min = t.strftime("%Y-%m-%dT%H:%M:%S")
 13   max = ((Date.new(x[0], x[1], 1)) - 1).strftime("%Y-%m-%dT23:59:59")
 14   return u + "?published-min=#{min}" + "&published-max=#{max}"
 15 end
 16 
 17 bloggerid = 'xxxxxxxxxxxx'
 18 t = '2010/12'
 19 p range_current_month(t, bloggerid)
 20 t = '2010/2'
 21 p range_current_month(t, bloggerid)
 22 

=>
"http://www.blogger.com/feeds/xxxxxxxxxxxx/posts/default?published-min=2010-12-01T00:00:00&published-max=2010-12-31T23:59:59"
"http://www.blogger.com/feeds/xxxxxxxxxxxx/posts/default?published-min=2010-02-01T00:00:00&published-max=2010-02-28T23:59:59"


もう少し短くできないかなと思うんだけど...。 ?

2009/05/19

BloggerAPI POST XML


# coding: utf-8
=begin
# post_xml.rb
# 2009-05-18.

# BloggerAPI POST Request で必要な XML の生成
<entry xmlns='http://www.w3.org/2005/Atom'>
<published>2009-06-01T00:00:00+09:00</published>
<app:control xmlns:app='http://www.w3.org/2007/app'>
<app:draft>yes</app:draft></app:control>
<title type='text'>test_title</title>
<category scheme='http://www.blogger.com/atom/ns#' term='Blogger'/>
<category scheme='http://www.blogger.com/atom/ns#' term='test'/>
<content type='xhtml'><div xmlns='http://www.w3.org/1999/xhtml'>
<p>xxx<a href='http://www.google.com'>google</a><br/><img src='ddd.png'/></p>
<pre><code>
  def aaa
  end
</code></pre>
<p>end.</p></div></content></entry>
# 実際は code element 以外,改行なし
=end

# You can redistribute it and/or modify it under the same terms as Ruby.
require "rexml/document"
require 'time'

module BloggerContentDiv

  def setup_div
    ary = @entry.content.strip.lines.to_a
    return nil if ary.empty?
    ary.each_with_index{|x,i|
      to_tag(x)
      tag_p if ary.size == i + 1
    }
    return @div
  end

  def to_tag(x)
    on = {"<pre>"=>"pre","<blockquote>"=>"blockquote"}
    off = {"</pre>"=>true,"</blockquote>"=>true}
    if on[x.strip]
      tag_p unless @str_plain.empty?
      @tag = on[x.chop]
    elsif off[x.strip]
      my_tag
      @tag = nil
    else
      @str_plain << x unless @tag
      @str_tag << x if @tag
    end
  end

  private

  def tag_p
    str = @str_plain.strip
    return nil if str.empty?
    @e_p = @div.add_element("p")
    str.each_line{|w|
      @m = /<(a)|<(img)|<(del)/.match(w)
      @m ? sub_tag_p(w) : @e_p.add_text(w.strip)
      @e_p.add_element("br") if /\n/.match(w)
    }
    @str_plain = ""
    return @div
  end

  def sub_tag_p(line)
    pre_str unless @m.pre_match.empty?
    if @m[1] then tag_a(line)
    elsif @m[2] then tag_img(line)
    elsif @m[3] then tag_del(line)
    end
    s = /<.*?\/>/.match(line)
    post_str(s) if s
  end

  def tag_del(line)
    del = /<del>(.*?)<\/del>/.match(line)
    @e_p.add_element("del").add_text(del[1])
  end

  def tag_img(line)
    href = /<img\ssrc=["'](.*?)["']/.match(line)
    alt = /alt=["'](.*?)["']/.match(line)
    return nil unless href
    img = @e_p.add_element("img",{'src'=>href[1]})
    img.add_attribute({'alt'=>alt[1]}) if alt
  end

  def tag_a(line)
    all = /<a\shref=["'](.*?)["']>(.*?)<\/a>/.match(line)
    @e_p.add_element("a",{'href'=>all[1]}).add_text(all[2])
  end

  def pre_str
    @e_p.add_text(@m.pre_match.chop)
  end

  def post_str(s)
    @e_p.add_text(s.post_match.chop) 
  end

  def my_tag
    case @tag
      when "pre" then tag_pre
      when "blockquote" then tag_block
    end
    @str_tag = ""
  end

  def tag_pre
    @div.add_text("\n")
    str = @str_tag
    e1 = @div.add_element("pre")
    e2 = e1.add_element("code").add_text("\n")
    e2.add_text(str)
    @div.add_text("\n")
  end

  def tag_block
    e1 = @div.add_element("blockquote")
    e2 = e1.add_element("p")
    @str_tag.strip.each_line{|w|
      e2.add_text(w.strip)
      e2.add_element("br") if /\n/.match(w)
    }
  end

end

class BloggerEntry

  attr_reader :title, :content, :published, :category, :control
  attr_accessor :editid, :updated

  def initialize
    @published = nil
    @control = nil
    @title = nil
    @content = nil
    @category = nil
    # these value, after post request
    @editid = nil
    @updated = nil
  end

  def setup(h)
    h.each{|k, v|
      i = "@#{k}".downcase.to_sym
      set_ins(i, v) if i_defined?(i)
    }
    return self
  end

  def to_xml_post
    return BloggerXML.new(self).post_data
  end

  private

  def set_ins(i,v)
    self.instance_variable_set(i, v)
  end

  def i_defined?(i)
    self.instance_variable_defined?(i)
  end

end

class BloggerXML

  include BloggerContentDiv

  def initialize(entry)
    @entry = entry
    @str_plain = ""
    @str_tag = ""
    @tag = nil
  end

  def post_data
    doc = REXML::Document.new()
    doc << REXML::XMLDecl.new(version="1.0", encoding="utf-8" )
    # entry
    @e = doc.add_element("entry", {'xmlns'=>'http://www.w3.org/2005/Atom'})
    # published
    set_published
    # App control element
    set_control
    # Title
    @e.add_element("title", {'type'=>'text'}).add_text(@entry.title.strip)
    # Category
    set_category
    # Content
    content = @e.add_element("content", {'type'=>'xhtml'})
    @div = content.add_element("div", {'xmlns'=>'http://www.w3.org/1999/xhtml'})
    setup_div
   return @e
  end

  private

  def set_published
    unless @entry.published
      n = Time.now.iso8601.to_s
    else
      n = Time.parse(@entry.published).iso8601.to_s
    end
    @e.add_element("published").add_text(n.to_s)
  end

  def set_control
    if @entry.control
      ac = @e.add_element("app:control",
        {'xmlns:app'=>'http://www.w3.org/2007/app'})
      ac.add_element("app:draft").add_text("#{@entry.control}")
    end
  end

  def set_category
    @entry.category.split(",").to_a.each{|c|
      @e.add_element("category",{"scheme"=>'http://www.blogger.com/atom/ns#',  "term"=>"#{c}"})
    }
  end

end

#--- test
title = 'test_title'
content =<<EOF 
xxxx<a href='http://www.google.com'>google</a>
<img src='ddd.png' alt='fff'>
<pre>
   def aaa
   end
</pre>
end.
EOF

category = "Blogger,test"
control = "yes"
h = {:title=>title, :content=>content, :category=>category, :control=>control, :published=>'2009-06-01'}
entry = BloggerEntry.new().setup(h)
puts data = entry.to_xml_post

#--- Start Post
# require 'gdata'
#begin
#  blogID = 'xxxxxxxxxxxx'
#  url = "http://www.blogger.com/feeds/#{blogID}/posts/default"
#  client = GData::Client::Blogger.new
#  client.source = sourcename
#  clientlogin('username', 'password')
#  client.post(url, data.to_s)
#rescue GData::Client::AuthorizationError => e
#  print "gData error\n"
#  print e.message
#end

content =<<EOF
中の pre は本当は小文字 < >で囲まれてる

修正
100 行目あたり
def pre_str
@e_p.add_text(@m.pre_match.chop)
@e_p.add_text(@m.pre_match)
end

def post_str(s)
@e_p.add_text(s.post_match.chop)
@e_p.add_text(s.post_match)
end

2009/05/17

BloggerAPI-パースエラー

ブラウザから手入力して投稿した記事の場合


 <content type='html'><div xmlns='http://www.w3.org/1999/xhtml'>

を含んでいなかったりする。入力してないのだから当たり前に、ない。その為 Blogger API を利用して GET Request し獲得した XML の content 要素は REXML ではパースエラーになってしまう。これを解消する方法をあれこれ考えてみたけれども挫折中。

パースエラーになるってことは例えばカテゴリをいっぺんに変換したくてもできない記事が存在してしまうってことになる。なぜなら、PUT Request でカテゴリを変更するリクエストを投げる時、その xml データには新規記事と全く同様の要素(タイトル、コンテンツ、カテゴリなど)が必要なのであって content は変更しないので含めませんでした、ではリクエストは通らない。

# 試しに content なしのデータを PUT リクエストしてみたところ BadRequest エラーだった。

でも、content を変えたいわけじゃなくてカテゴリーだけ変えたい。content は元のままを維持したい。それで Get で得られた xml の content をパースしてその要素をそのまんま PUT リクエストデータの content にしてしまえば楽だしミスがない。でもパースできないやつがあるってことが分かった。なぜなら div がないから。あるいはひょっとしてタイプミスして変なタグいれちゃったからなんだけど.. orz

# 結局、BloggerAPI からコントロールしたければ全ての記事の content には div 要素が必要だってことは明白になったので元の文章がちゃんとテキストで保存されていて尚かつ変更しやすそうな記事だけ div 要素を加えることができた。

簡単なテスト


  # coding: utf-8
 str=<<EOF
  # ここにパースエラーになった記事の content 要素内容をはりつける。
  # Get Request で得られた XML の entry.elements['content'].text
 EOF

  doc = REXML::Document.new()
  doc << REXML::XMLDecl.new(version="1.0", encoding="utf-8" )
  # Entry element
  x = doc.add_element(
  "entry",
  {'gd'=>'http://schemas.google.com/g/2005','xmlns'=>'http://www.w3.org/2005/Atom'}
  )
  begin
   # div 要素が存在し かつ ほかの要素も xhtml的に正しければこの行でパースが成功する。
    div = REXML::Document.new(str)
    div.add_namespace({ 'xmlns'=>'http://www.w3.org/1999/xhtml'})
    c = x.add_element('content', {'type'=>'xhtml'})
    c.add_element(div)
    puts c
  rescue REXML::ParseException
    # div 要素がない。あるいは div があってもタグがどっかおかしかったりとか変な br があったりとか? 未知
    # 記事中に Ruby の継承である記号があらわれただけでエラーになったりする
    # gstr = str.gsub(" < ", ' &lt; ').gsub("<<","&lt;&lt;")
    # この先どうすべきやら
  end

memo
カテゴリーを指定して Get Request を発行する場合のURL
#参照
# http://code.google.com/intl/ja/apis/blogger/docs/2.0/developers_guide_protocol.html

# URL 例:
# http://www.blogger.com/feeds/blogID/posts/default/-/Fritz/Laurie

2009/05/09

update gdata-ruby 1.1

download gdata-1.1.0.gem (2009.04.28)
http://code.google.com/p/gdata-ruby-util/downloads/list

% gem19 unpack gdata-1.1.0.gem 
# 
# Unpacked gem: 'download/gdata-1.1.0'
% diff gdata-1.0.0/lib/gdata/ gdata-1.1.0/lib/gdata/
% vi gdata-1.1.0/lib/gdata.rb
# require 'jcode'
# $KCODE = 'UTF8'

# 2009-05-16 category 変更
# 2010-01-06 最新 mblogger

2009/04/02

Blogger API 再考

[2011-06-28]
# 最新
https://github.com/midore/mblogger
https://github.com/midore/xblogger
# 関連する記事
# "Blogger"ラベルがついた全ての記事
# 下記は動かないかもしれません


再考
Blogger API から Postしてみる
# Blogger API 紹介ペーージ
http://code.google.com/intl/ja/apis/blogger
# じっくり読んでみたガイド
Developer's Guide: Protocol
# Google 翻訳 以前にくらべてわかりやすくなったような気がする。
翻訳ページ

It can authenticate using either of two approaches: AuthSub proxy authentication or ClientLogin username/password authentication.

認証には2通りありひとつが AuthSubプロキシ認証、もうひとつが、ClientLogin。認証方法はどちらでもかまわないらしい。(authentication documentation.をみにいくとさらに他の種類の認証方法もあった。)
# 認証の詳細
http://code.google.com/intl/ja/apis/gdata/auth.html
# gdata-1.0.0
gdata-ruby-util
私がダウンロードした Ruby 用ライブラリ gdata-1.0.0 は clientLogin 方式なのだと思う。(lib/Blogger.rb をみると class Base を継承していて class Base は account, password を必要としている。)なので、このライブラリを使用して Blogger.new するってことは自動的に clientLogin 方式を採用したことになる。たぶん。

# gem を通して使わないので gem を解凍
% gem19 unpack gdata-1.0.0.gem
% vi  gdata-1.0.0/lib/gdata.rb
# ここをはずすことで Ruby 1.9.1 でも動くようになる。
# require 'jcode'
# $KCODE = 'UTF8'
# 新しく作る起動用ファイルの冒頭。
# パスに gdata のパスを加える(Ruby 1.9.1 のgem をつかってないので)
% more myapp.rb
# coding: utf-8
$LOAD_PATH.push('/path/to/gdata-1.0.0/lib')
# gdata-1.0.0/lib/gdata.rb
require 'gdata'
require "rexml/document"
require 'time'
############# New 
# インスタンス生成 ダウンロードした gdata-1.0.0 ライブラリの
# Blogger クラスを呼び出す。
bl = GData::Client::Blogger.new
# bl.source には自分のプログラムの名前とバージョン名をいれる。
# いれなくても動くと思う。
bl.source = 'myapp_v1'
# 認証されたかの確認 。
# 認証に失敗した場合は エラーメッセージが表示される。
p token = bl.clientlogin(account, pass)
print "---------- Start\n"
############# Get 1
# 宛先URL : http://www.blogger.com/feeds/profileID/blogs
# profileID と blogID は異なるので注意。私も間違えた。
# profileID の部分は自分のブログの meta タグ内の
# link rel='me' href="http: で始まる url に含まれるID
# 以下を実行すると自分のブログに関連する URL  など
# xmlデータが返ってくる。最初の確認に必要な情報をうるための操作。
# url = 'http://www.blogger.com/feeds/xxxxx/blogs'
# p feed = bl.get(url).to_xml
# puts feed
############# Get 2
# 宛先URL : 
# http://www.blogger.com/feeds/blogID/posts/default?\
# published-min=2008-03-16T00:00:00&published-max=2008-03-24T23:59:59
# blogID は、Get 1で得られた xml に記載されている URL を使う。
# 日付を範囲指定するとその日付範囲内に投稿されたエントリー
#(下書きを含む)の xml がかえってくる。
# min と max で指定
# url = 'http://www.blogger.com/feeds/xxxxx/posts/default?\
published-min=2009-04-01T00:00:00&published-max=2008-04-03T00:00:00'
# res = bl.get(url).to_xml
# puts res
############# Get 3
# 宛先URL : http://www.blogger.com/feeds/blogID/posts/default
# 最新のエントリが[0] その一つ前が[1] (下書き含む)
# feed = bl.get(url).to_xml
# puts feed.get_elements('entry')[0]
############# Post
# 宛先URL : http://www.blogger.com/feeds/blogID/posts/default
#  <app:control xmlns:app='http://www.w3.org/2007/app'>
#    <app:draft>yes</app:draft>
#  </app:control>
# を含めると下書きとして保存される。
# 投稿と同時に公開したい場合はこの要素を削除。
# category ... term="Blogger"/> の 
# attribute term=''  の部分がラベルとなる。複数可。
# str = 上記ガイドの POST 参照 
url = 'http://www.blogger.com/feeds/xxxxx/posts/default'
p res = bl.post(url, str)
p res.status_code
# =>
#<GData::HTTP::Response:...........@status_code=201>
# 201
############# PUTS
# 宛先URL : http://www.blogger.com/feeds/blogID/posts/default/postID
# edit_uri は 宛先URL。Get で獲得したエントリー XMLの 
# entry エレメントにふくまれる link href ... rel='edit' /> の href=''の部分。 
# entry要素は、
# entry xmlns='http://www.w3.org/2005/Atom' gd='http://schemas.google.com/g/2005'
# POST で使用した entry のネームスペースのままだとうまくいかない。
# attribute gd='' が必要のようだ。よくわからないけど。
# edit_uri = 'http://www.blogger.com/feeds/xxxxx/posts/default/xxxxxxx'
# response = bl.put(edit_uri, entry)
# puts response.status_code

# 2009-05-16 category 変更. 改行修正

2009/03/28

Blogger API から Putsしてみる

[2011-06-28]
# 最新
https://github.com/midore/mblogger
https://github.com/midore/xblogger
# 関連する記事
# "Blogger"ラベルがついた全ての記事

参考ドキュメント
Using Ruby with the Google Data APIs
http://code.google.com/intl/ja/apis/gdata/articles/using_ruby.html
Google Data on Rails
http://code.google.com/intl/ja/apis/gdata/articles/gdata_on_rails.html
メモ

  entry.add_namespace('http://www.w3.org/2005/Atom')
  entry.add_namespace('gd','http://schemas.google.com/g/2005')

追記
http://midorex.blogspot.com/search/label/Blogger
# 2009-05-16 category 変更

2009/03/25

Blogger API からラベルつき投稿

[2011-06-28]
# 最新
https://github.com/midore/mblogger
https://github.com/midore/xblogger
# 関連する記事
# "Blogger"ラベルがついた全ての記事
# 下記は動かないかもしれません。

をするためには...いろいろためした結果わかったこと

def make_doc(title, content)
 n = Time.now.iso8601
 doc = REXML::Document.new()
 doc << version="1.0" encoding="utf-8"
 # 2009-05-18 加筆訂正
 entry = doc.add_element("entry", {'xmlns'=>'http://www.w3.org/2005/Atom'})
 #content type='xhtml'><div xmlns='http://www.w3.org/1999/xhtml'
 content = entry.add_element("content", {'type'=>'xhtml'})
 div = content.add_element("div", {'xmlns'=>'http://www.w3.org/1999/xhtml'})
 div.add_text(content)
 entry.add_element("published").add_text(n.to_s)
 entry.add_element("title", {'type'=>'text'}).add_text(title)
 entry.add_element("category",{"scheme"=>'http://www.blogger.com/atom/ns#',  "term"=>'Blogger'})
 con = entry.add_element("content", {'type'=>'html'})
 
 #con.add_text(content)
 
 return doc
end

書き加えた箇所

 entry.add_element("category",{"scheme"=>'http://www.blogger.com/atom/ns#', "term"=>'Blogger'})

category エレメントの term => 'xxxx' で指定した文字列がラベルとなって反映されるようだ。
このメソッドで作成する XML ドキュメントは、ひょっとして何かが足りないかもしれないし何かが不要なのかもしれないけども、
投稿には成功している。です。
追記訂正 2009-04-10
http://midorex.blogspot.com/search/label/Blogger
2009-05-19 作り直しBloggerAPI POST XML

2009/03/03

Blogger API から Postしてみる

[2011-06-28]
# 最新
https://github.com/midore/mblogger
https://github.com/midore/xblogger
# 関連する記事
# "Blogger"ラベルがついた全ての記事
# 下記は動かないかもしれません。

gData , Blogger API などで検索
http://blogger.ukai.org/2009/02/ruby2009.html
ここでGoogle が提供する gdata-ruby-util の存在を知った。
gdata_on_rails.html
Rails を使用するようだ?けどRails を使っていなくても参考になった。
gdata-ruby-util
から gdata-1.0.0.gem を手動ダウンロード。
% mv gdata-1.0.0.gem.tar gdata-1.0.0.gem
% gem19 unpack gdata-1.0.0.gem
Google Search keyword: gem 展開
参考になったページ
http://d.hatena.ne.jp/walf443/20080920/1221916162
http://blog.s21g.com/articles/1301
ダウンロードした gdata-1.0.0 をRuby 1.9.1 でうごくように少しかきかえた
% vi gdata-1.0.0/lib/gdata.rb 
# 20 行目あたりを編集。
# This is for Unicode "support"
#require 'jcode'
#$KCODE = 'UTF8'
---

# coding: utf-8
# post-gdata.rb
$LOAD_PATH.delete(".")
$LOAD_PATH.push('/path/to/BloggerAPI/gdata/gdata-1.0.0/lib')
require "rexml/document"
require 'time'
require 'gdata'
class MyBlogger
  def initialize(ary)
    @ary = ary
    @client = GData::Client::Blogger.new
  end
  def base(account, pass, url)
    doc = txt_to_xml
    # get token
    @client.clientlogin(account, pass)
    @client.prepare_headers
    # {"GData-Version"=>"2", "User-Agent"=>"GoogleDataRubyUtil-AnonymousApp", "Content-Type"=>"application/atom+xml"}
    @client.post(url, doc)
    #=> GData::HTTP::Response: @body=" ?xml version='1.0' .........@status_code=201
  end
  def txt_to_xml
    title = @ary[0].chomp
    content = @ary[2..@ary.size].join("").strip.gsub("\n","
")
    return make_doc(title, content)
  end
  def make_doc(title, content)
    n = Time.now.iso8601
    doc = REXML::Document.new()
    doc << REXML::XMLDecl.new(version="1.0", encoding="utf-8" )
    entry = doc.add_element("entry", {"xmlns" => "http://www.w3.org/2005/Atom"})
    entry.add_element("published").add_text(n.to_s)
    entry.add_element("title", {'type'=>'text'}).add_text(title)
    con = entry.add_element("content", {'type'=>'html'})
    con.add_text(content)
    return doc
  end
end

# File をあたえる
txt_ary = ARGF.readlines
# この url は 自分の Blogger URL トップページソース内
# link rel='self' type='application/atom+xml' で始まる行のリンク先
url = 'http://midorex.blogspot.com/feeds/posts/default'
# Blogger のアカウントとパスワード
account = 'xxx'
pass = 'xxx'
m = MyBlogger.new(txt_ary)
p m.base(account, pass, url)
30 行目あたりの真意は
content = @ary[2..@ary.size].join("").strip.gsub(改行、<br/>)
このBlogger に投稿すると本当の br と解釈されてしまうためコードが消えてるだけ。
pre とか、code といったタグが出現したらその中の文字列を解釈しないようになっていたら便利なんだけど...
それともなんか方法があるのかな。
Ruby 1.9.1 で実行
% ruby19 post-gdata.rb textdata.txt
textdata.txt の1行目がタイトルに、2行目以下がコンテンツに。
投稿に成功すると@status_code=201 が返る。
+++
追記 
2009-04-02 Blogger API 再考
2009-05-19 category 変更
2009-05-19 作り直しBloggerAPI POST XML
2010-01-06 最新 mblogger