Article

Ploneからデータをエクスポート

※ 商品リンクから購入されると少額の報酬が発生することがあります。

訳あって、Ploneからデータの抜き出しをすることになりました。

難しくてよくわからないので、ゴリゴリのエクスポートスクリプトを書きました。どうでもいいものなので、公開しちゃいます。

__Broken_Persistent_ っていうぶっ壊れてるっぽいオブジェクトにはまりました。

用途に応じて修正しないと求める動作はしませんよ:-)

Data.fsは必ずコピーしたも のを使ってください。

  • 日本語対策。Pythonのデフォルトエンコーディングを確認

      $ cat /usr/lib/python2.4/site-packages/sitecustomize.py
    
      import sys
      sys.setdefaultencoding('utf-8')
  • 環境変数。Plone(Zope)の起動シェルからかっぱらった。

      PYTHON="/usr/bin/python"
      ZOPE_HOME="/usr/lib/zope"
      INSTANCE_HOME="/var/lib/zope"
      CONFIG_FILE="/var/lib/zope/etc/zope.conf"
      SOFTWARE_HOME="/usr/lib/zope/lib/python"
      PYTHONPATH="$SOFTWARE_HOME"
      export PYTHONPATH INSTANCE_HOME SOFTWARE_HOME
  • ゴリゴリのスクリプト。Pythonシェルから実行ね。

      import os
      import sys
      import codecs
    
      from ZODB import FileStorage, DB
      storage = FileStorage.FileStorage('/path_to/Data.fs')
      db = DB(storage)
      connection = db.open()
      root = connection.root()
    
      plone = root.data['Application']['plone'] #必要なオブジェクトまでは頑張って辿ろう
    
      targets = [plone] #複数でも良いよ
    
      BASE_DIR = os.getcwd() #出力場所に注意
    
      error_dict = {} #いっぱいエラーが出ると嫌だから辞書にしまっちゃう
    
      def walk_through(base_dir, target):
          try:
              target.__Broken_Persistent__ #なんじゃ、こりゃ
              target = target.__Broken_state__
              cur_dir = os.path.join(base_dir, target['id'])
              t_dir = target.keys()
          except Exception:
              cur_dir = os.path.join(base_dir, target.id)
              t_dir = dir(target)
          if not os.path.exists(cur_dir):
              os.mkdir(cur_dir)
          os.chdir(cur_dir)
    
          for d in t_dir:
              v = False
              try:
                  v = target[d]
              except Exception, e:
                  try:
                      v = target.__getattribute__(d)
                  except:
                      error_dict['%s[%s]' % (target, d)] = target
                      pass
              if v:
                  export_data(cur_dir, v)
    
      def export_data(cur_dir, v):
          if 'ProjectFolder' in str(v.__class__) or 'ATFolder' in str(v.__class__) or 'DocumentFolder' in str(v.__class__):
              walk_through(cur_dir, v) #フォルダだったら再帰するよん。必要なフォルダタイプを指定してね。
          elif 'ATDocument' in str(v.__class__): #ドキュメント
              try:
                  f = codecs.open(os.path.join(cur_dir, '%s.html' % (v.id.strip(),)), 'w', encoding='utf-8')
                  try:
                      body = v.getText()
                  except Exception:
                      body = v.getRawText() #なんだろうねぇ
                  f.write('<title>%s</title>\n%s' % (v.title, body, ))
                  f.close()
              except Exception, e:
                 print 'Document: %s' % v
          elif 'ATFile' in str(v.__class__) or 'ATImage' in str(v.__class__):
              try:
                  try:
                      fn = v.getFilename()
                  except Exception:
                      fn = v.Title() #拡張子が消えちゃうよ
                  f = open(os.path.join(cur_dir, '%s' % fn), 'w')
                  f.write(str(v))
                  f.close()
              except Exception, e:
                 print 'File: %s' % v
    
    
      for t in targets:
          walk_through(BASE_DIR, t)
    
      print error_dict

Prev Entry

Next Entry