<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>santochancf (SantoChan)</title>
    <link>https://ruby-china.org/santochancf</link>
    <description>十年一剑情如梦  再向苍天问仙踪</description>
    <language>en-us</language>
    <item>
      <title>从主流文档中提取内容的开源工具比较和选择</title>
      <description>&lt;p&gt;在 Fiberead，需要将一些常见格式的文档（如 Word，PDF 等）中的文字提取出来，方便进一步分析和处理。刚开始处理的文档很少，就「Quick and Dirty」的使用 OpenOffice 的&lt;code&gt;headless&lt;/code&gt;模式来做了转换。随着业务扩展，需要处理的文档越来越多，大量文档的的并行处理会启动很多 OpenOffice 的进程，占用过多的系统资源，从而导致一些提取工作失败。虽然通过重试机制还可以保证处理完成，但这种方案明显已经不稳定了。所以花了一些时间进行改进了一下文本提取任务。这里顺便比较一下常见的开源工具。&lt;/p&gt;
&lt;h2 id="OpenOffice/LibreOffice"&gt;&lt;a href="http://www.openoffice.org/" rel="nofollow" target="_blank" title=""&gt;OpenOffice/LibreOffice&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;OpenOffice/LibreOffice（后简称为OpenOffice）是最初的选择方案。主要一个优势是可以处理Doc（Word 97）格式的文档。OpenOffice 使用&lt;code&gt;headless&lt;/code&gt;模式可以一个命令完成文件转换，但每次都要启动一下 OpenOffice 进程。通过阅读文档发现，OpenOffice 是可以通过服务端模式启动，监听一个端口来处理转换请求。如：&lt;/p&gt;

&lt;p&gt;&lt;code&gt;/Applications/LibreOffice.app/Contents/MacOS/soffice --headless --accept="socket,host=127.0.0.1,port=8100;urp;"&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;但是接口方式是&lt;a href="https://en.wikipedia.org/wiki/Universal_Network_Objects" rel="nofollow" target="_blank" title=""&gt;UNO&lt;/a&gt;. 然后原生 Language Binding 里没有 Ruby。这样就无法通过 Ruby 直接调用这个服务。使用 Ruby 实现一个又会花费很多时间。&lt;/p&gt;

&lt;p&gt;由于支持 Python，所以旧有 Python 实现的&lt;a href="https://github.com/dagwieers/unoconv" rel="nofollow" target="_blank" title=""&gt;UnoConv&lt;/a&gt;。这个工具封装了一下监听，比较方便调用：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;unoconv &lt;span class="nt"&gt;--listener&lt;/span&gt;
unoconv &lt;span class="nt"&gt;-f&lt;/span&gt; txt test.doc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样可以通过启动这个服务，通过调用&lt;code&gt;unoconv&lt;/code&gt;命令完成转换。
基于 OpenOffice 的处理办法都有一个通用的问题，就是输出无法支持 STDOUT，使用 Ruby 做 Wrapper 时就还需要创建读取临时文件来处理。&lt;/p&gt;
&lt;h2 id="Tika"&gt;&lt;a href="http://tika.apache.org/" rel="nofollow" target="_blank" title=""&gt;Tika&lt;/a&gt;&lt;/h2&gt;
&lt;p&gt;Apache Tika (后简称 Tika) 是一个 Java 实现的文档文本提取工具，也支持提取一些文档的的元数据。Tika 可以支持更多的格式，包括并不限于：MS Office 的各种格式，iWorks，CAD，甚至图片和视频的文本也可以提取。Tika 是一个 Java Library, 所以可以通过程序调用。同时也支持命令进行转换，如：
&lt;code&gt;java -jar tika.jar -t test.doc&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;同时还单独提供了 Server 版，可以通过 HTTP 的接口转换文档：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;java &lt;span class="nt"&gt;-jar&lt;/span&gt; ./tika-server-1.11.jar
curl &lt;span class="nt"&gt;-T&lt;/span&gt; test.docx http://localhost:9998/tika &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s2"&gt;"Accept: text/plain
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种方式对 Ruby 来说更加友好。可以方便使用以下代码完成转换&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'curb'&lt;/span&gt;

&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Curl&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Easy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:9998/tika"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Accept"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"text/plain"&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;http_put&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file_path&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;econding: &lt;/span&gt;&lt;span class="s1"&gt;'UTF-8'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;read&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;body_str&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;force_encoding&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'UTF-8'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="简单比较"&gt;简单比较&lt;/h2&gt;&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;名称&lt;/th&gt;
&lt;th&gt;调用方式&lt;/th&gt;
&lt;th&gt;运行内存占用&lt;/th&gt;
&lt;th&gt;安装文件大小&lt;/th&gt;
&lt;th&gt;性能比较&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenOffice&lt;/td&gt;
&lt;td&gt;Ruby -&amp;gt; Python process -&amp;gt; OpenOffice UNO&lt;/td&gt;
&lt;td&gt;40MB + 19MB*N(OpenOfficePython 进程)&lt;/td&gt;
&lt;td&gt;约 1GB&lt;/td&gt;
&lt;td&gt;1000 20KB Doc 文件耗时 4 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache Tika&lt;/td&gt;
&lt;td&gt;Ruby -&amp;gt; HTTP PUT Request&lt;/td&gt;
&lt;td&gt;100MB&lt;/td&gt;
&lt;td&gt;56MB&lt;/td&gt;
&lt;td&gt;1000 20KB Doc 文件耗时 160 秒&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h2 id="结论"&gt;结论&lt;/h2&gt;
&lt;p&gt;使用 Apache Tika 可以快速完成升级，并且便于后面扩展。所以可以做一个 Upstart Script，方便将 Tika 运行为服务：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;description     "Apache Tika Server"

start on filesystem or runlevel [2345]
stop on shutdown

respawn
respawn limit 3 12

exec java -jar /opt/tika/tika-server-1.11.jar
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href="https://gist.github.com/santochan/2e6ee74b2c894f24175a" rel="nofollow" target="_blank" title=""&gt;Gist&lt;/a&gt;&lt;/p&gt;</description>
      <author>santochancf</author>
      <pubDate>Sat, 31 Oct 2015 17:06:41 +0800</pubDate>
      <link>https://ruby-china.org/topics/27905</link>
      <guid>https://ruby-china.org/topics/27905</guid>
    </item>
    <item>
      <title>关于 ActiveRecord 使用 set_table_name 的诡异问题</title>
      <description>&lt;p&gt;简单使用 ActiveRecord 来做数据查询&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Tmnl&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ActiveRecord&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Base&lt;/span&gt;   
  &lt;span class="n"&gt;set_table_name&lt;/span&gt;  &lt;span class="s2"&gt;"tmnl_status"&lt;/span&gt;  
  &lt;span class="c1"&gt;#set_primary_key "STATUS_ID"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="no"&gt;Tmnl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但是这个表，不知特殊在哪里，其他表都没问题，总会在查询是报错：&lt;/p&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ArgumentError: wrong number of arguments &lt;span class="o"&gt;(&lt;/span&gt;1 &lt;span class="k"&gt;for &lt;/span&gt;0&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>santochancf</author>
      <pubDate>Thu, 20 Sep 2012 15:35:30 +0800</pubDate>
      <link>https://ruby-china.org/topics/5656</link>
      <guid>https://ruby-china.org/topics/5656</guid>
    </item>
    <item>
      <title>如何在 fields_for 中获取序号</title>
      <description>&lt;p&gt;通过 form 结合 fields_for 可以实现迭代。
请问如何获取迭代中显示序号……&lt;/p&gt;

&lt;p&gt;&amp;lt;%= f.fields_for :line_items do |line| %&amp;gt; &lt;/p&gt;

&lt;p&gt;#how to get the index
&amp;lt;%end %&amp;gt; &lt;/p&gt;</description>
      <author>santochancf</author>
      <pubDate>Mon, 30 Jul 2012 00:47:37 +0800</pubDate>
      <link>https://ruby-china.org/topics/4631</link>
      <guid>https://ruby-china.org/topics/4631</guid>
    </item>
  </channel>
</rss>
