おでんはじめました。

required ちくわぶ and 巾着,optional はんぺん.

cakebox/cakephpでphpunitが認識されない

cakeboxでcakephp(2.7)とphpunit(4.4.4)がインストールされているけどcakephpからphpunitが認識されない件。

ブラウザからtest.phpを表示すると、

Warning include(PHPUnit/autoload.php) failed open stream...

とか表示されてテストを実行できない。

composer.jsonのvendor-dirディレクトリを修正して解決。

(修正前)

"config": { "vendor-dir": "app/Vendor/Composer" },

(修正後)

"config": { "vendor-dir": "Vendor/Composer" },

app/Vendor/Composer/phpunit/...となればOKみたい。

cakephpがどこでphpunitのディレクトリを読み込んでいるのかはよくわからない。

WordPressの投稿をJSON形式で受け取る

XMLRPCを使って最近の投稿をJSON形式で受け取るまで。

XMLRPCのライブラリーをWordPressにコピーする

下記からIXR_Library.phpをダウンロードして自分のWordPressのサイトへコピーする。

http://scripts.incutio.com/xmlrpc/ The Incutio XML-RPC Library for PHP

(ページの上にある「Download the Library」をクリック)

投稿をJSONで受け取るPHPを書く

下記をgetposts.phpとしてWordPressのサイトへ保存する。

変更箇所はサイト名、ユーザー名、パスワード。

文字コードUTF-8などWordPressに合わせる。

<?php
// inctioのライブラリ呼び出し
include_once('IXR_Library.php');

$wp_username = 'admin';
$wp_password = 'admin';
$siteurl     = 'http://sample.jp/';

$filter = array( 
  'number' => 10,   //最近の10件取得
  'offset' => 0,
  );
$client = new IXR_Client( $siteurl . 'xmlrpc.php' );
$status = $client->query(
  "wp.getPosts", //POSTを取得する
  1, // blog ID: 通常は1、マルチサイト時変更
  $wp_username, // ユーザー名
  $wp_password, // パスワード
  $filter
  );
$posts = $client->getResponse(); //arrayで戻ってくる
echo json_encode( $posts );  //JSONで返す

確認する

http://sample.jp/getposts.phpへアクセスしてJSONが戻ってくればOK。

うまくいかない時

ブラウザで表示が真っ白の時はphpの構文が違ってる可能性があるのでphp -l getposts.phpで構文チェックするとか。

IXR_Library.phpのエラー内容がわかりづらい。ユーザー名とパスワードが違ってないか、new IXR_Clientで渡すURLが違ってないか確認など。

ShapeFontからfreetype6.dllの関数が呼べない時

SharpFontを使ってfreetype.dllの関数が呼び出せない場合がある。

'freetype6.dll' の 'FT_Get_CID_From_Glyph_Index' というエントリ ポイントが見つかりません。

こういう場合はfreetypeのプロジェクトにftcid.cを追加してfreetype.dllをコンパイルすればOK。

右クリック右クリック管理者権限で実行しかできないと思ってた

GitBashを右クリック右クリック管理者権限で実行がめんどくさいなあと思ったら、コマンドプロンプトから管理者権限で動かせると。

powershell -command "Start-Process -wait \"C:\Program Files (x86)\Git\bin\sh.exe\" -argumentlist \"--login -i\" -Verb runas"

参考: Windows で sudo なことをする。 | みむらの手記手帳

LINQ to XMLが便利すぎてメモ

下記のsample.xmlに対して

<?xml version="1.0" encoding="UTF-8" ?>
<LIST>
  <文字 ID="00001">
    <UCS>4E00</UCS>
    <CID>1200</CID>
  </文字>
  <文字 ID="00002">
    <UCS>4E05</UCS>
    <CID>14297</CID>
  </文字>
</LIST>

<文字>のタグの一覧を取得する

XDocument xdoc = XDocument.Load("sample.xml");
//戻り値はIEnumerable<XElement>
var lst = from moji in xdoc.Descendants("文字")   
          select moji;
foreach (var/*XElement*/ elem in lst)
{
  Console.WriteLine("TAG NAME={0}", elem.Name); //文字
  var ucs = elem.Element("UCS");   //子供のUCSを取得
  Console.WriteLine("UCS={0}", ucs.Value/*タグに挟まれた文字列*/);
}

IDの一覧を取得する

XDocument xdoc = XDocument.Load("sample.xml");
//戻り値はIEnumerable<string>
var lst = from moji in xdoc.Descendants("文字")   
          select moji.Attribute("ID").Value;

foreach (var/*string*/ id in idlst)
{
  Console.WriteLine("ID={0}", id);
}

こんなに簡単だとプログラムの書き方を忘れる。

C#でリソースファイルからテキストを取得する

いつも忘れてしまうのでメモ。

VSでファイルを追加してプロパティのビルドアクションを「埋め込まれたリソース」にするのを忘れないこと。

//現在のコードを実行しているAssemblyを取得
System.Reflection.Assembly myAssembly = System.Reflection.Assembly.GetExecutingAssembly();

//ネームスペースがkj.sample、リソース名がtest.xmlの場合
System.IO.StreamReader sr = new System.IO.StreamReader(myAssembly.GetManifestResourceStream("kj.sample.test.xml"), Encoding.UTF8);
if (sr == null) throw new Exception("リソースを取得できない");
string s = sr.ReadToEnd();
sr.Close();

リソースの一覧の取得方法もメモ。

//指定されたマニフェストリソースを読み込む
string[] resnames=myAssembly.GetManifestResourceNames();
foreach (string res in resnames) {
  Console.WriteLine("resource {0}",res);
}

品詞分解してWordPressで検索するまで(その2、投稿編)

その1で作成したテキストを使ってWordPressへ一括で投稿するまでをやります。

XML-RPCの準備

WordPressへの投稿はXML-RPCを使う。 JSON REST APIはよくわからなかったので次の課題(汗。

XML-RPCを使うとWordPressの外側から投稿やカテゴリーの操作など一通りの作業ができる。 すべてのAPIは下記参照。

XML-RPC WordPress API « WordPress Codex

XML-RPCのライブラリはいくつかあるらしいけどincutioが使いやすそうだったのでこれを使う。

The Incutio XML-RPC Library for PHP

上記からIXR_Library.phpをダウンロードしてサイトの任意の場所へコピーする。

IXR_Library.phpの使い方

wp.newPostで投稿する場合。

<?php
/* inctioのライブラリ呼び出し */
include_once(‘IXR_Library.php');

/* 対象とするWordPressのサイト */
$client = new IXR_Client(“http://sample.co.jp/xmlrpc.php”);
$status = $client->query(
  "wp.newPost", //使うAPIを指定(wp.newPostは、新規投稿)
  1, // blog ID: 通常は1、マルチサイト時変更
  $wp_username, // ユーザー名
  $wp_password, // パスワード
  array(
    'post_author' => 2, // 投稿者ID 未設定の場合投稿者名なしになる。
    'post_status' => 'publish', // 投稿状態
    'post_title' => 'タイトル', // タイトル
    'post_content' => '投稿本文', // 本文
    'terms' => array('category' => array(1)) // カテゴリ追加
  )
);
if(!$status){
  die('Something went wrong - '.$client->getErrorCode().' : '.$client->getErrorMessage());
} else {
  $post_id = $client->getResponse(); //返り値は投稿ID
}

post.phpを作成する

投稿用のphp(post.php)を作成する。このphpC#から呼び出して使う。

作成したpost.phpWordPressのサイトの任意のフォルダにコピーする。

今回はWordPressのサイトの下のxmlrpcフォルダを作成してそこにコピーする。

  • フォルダ構成 www.sample.co.jp(WordPressのサイト)

 xmlrpc.php

 xmlrpcフォルダ

  IXR_Library.php

  post.php

  • 全部のソース(post.php
<?php
/**
品詞分解されたデータを投稿する
*/
include_once('IXR_Library.php');  //inctioのライブラリ呼び出し

//WordPressのサイトのルートにはxmlrpc.phpがある(初めから?)
$client = new IXR_Client("http://" . $_SERVER['SERVER_NAME'] . "/xmlrpc.php");

$user = $_POST['user']; //ユーザー名
$pass = $_POST['pass']; //パスワード

$data = array(
  'post_author'  => 1, // 投稿者ID 未設定の場合投稿者名なしになる。
  'post_status'  => 'publish', // 投稿状態
  'post_title'   => $_POST['title'],
  'post_content' => $_POST['content'],
);
$honbunlst  = mb_split( ",", $_POST['honbun'] );
$katsuyolst = mb_split( ",", $_POST['katsuyo'] );
$hinshilst  = mb_split( ",", $_POST['hinshi'] );
//本文、品詞、活用を一つずつカスタムフィールドとして登録する
for( $i=0; $i<count($honbunlst); $i++ ){
  $data['custom_fields'][] =
    array( 'key' => 'honbun', 'value' => $honbunlst[$i] ); 
  $data['custom_fields'][] =
    array( 'key' => 'katsuyo', 'value' => $katsuyolst[$i] ); 
  $data['custom_fields'][] =
    array( 'key' => 'hinshi', 'value' => $hinshilst[$i] ); 
}

$status = $client->query(
  "wp.newPost", //wp.newPostは、新規投稿
  1, // blog ID: 通常は1、マルチサイト時変更
  $user, // ユーザー名
  $pass, // パスワード
  $data  //追加するデータ
);

if(!$status){
  $res = array (
    'status' => 'error',
    'msg' => $client->getErrorMessage(), 
    'code' => $client->getErrorCode(),
  );
  echo json_encode( $res );  //JSONで返す
  return;
}
$post_id = $client->getResponse(); //返り値は投稿ID
$res = array(
  'status' => 'ok',
  'postid' => $post_id,
);
echo json_encode( $res );  //JSONで返す

mecabのテキストを読み込んで「。」ごとに本文と品詞・活用のデータを抽出しpost.phpを呼び出すC#を作成する。

C#の全部のソースは下記参照してください。

masatoru/xmlrpcsample · GitHub

CreateTextCore.cs(抜粋)
PostStatus postHonbun (string title, List<string> honbunlst, List<string> hinshilst, List<string> katsuyolst)
{
  try {
     string url = string.Format ("{0}/xmlrpc/post.php", url_);  //上記で作成したpost.phpへPOSTする
    //Console.WriteLine("POST={0}",url);
    var client = new System.Net.Http.HttpClient ();

  Dictionary<string, string> dict = new Dictionary<string, string>{
  { "user", user_ },//ユーザー名
  { "pass", pass_ },//パスワード
  { "title", title },//タイトル
  { "content", string.Join("",honbunlst.ToArray())  },//本文
  //mecabでばらした本文、品詞、活用形はカンマ区切りでPHPに渡す
  //PHP(post.php)側で配列で受け取ってカスタムフィールドとして登録する
  { "honbun", string.Join(",",honbunlst.ToArray()) },
  { "hinshi", string.Join(",",hinshilst.ToArray()) },
  { "katsuyo", string.Join(",",katsuyolst.ToArray()) },
  };

  //Dictionaryの値の文字列が長いとエラーになるので注意
  var content = new FormUrlEncodedContent (dict);       
  var response = client.PostAsync (url, content).Result;

  string json = response.Content.ReadAsStringAsync ().Result;
  return Newtonsoft.Json.JsonConvert.DeserializeObject<PostStatus> (json);
  } catch (Exception ex) {
    throw new Exception ("POSTできない MSG=" + ex.Message);
  }
}