From 06d4652807deb543df2603a8605f325ac7c9f9a8 Mon Sep 17 00:00:00 2001 From: helmutm Date: Wed, 7 Mar 2007 19:32:15 +0000 Subject: [PATCH] provide text converters for XLS and PPT git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1626 fd906abe-77d9-0310-91a1-e0d9ade77398 --- text/README.txt | 29 ++++++++++++++++++++++++ text/doc.py | 5 ++--- text/pdf.py | 1 - text/ppt.py | 48 ++++++++++++++++++++++++++++++++++++++++ text/testfiles/mary.odp | Bin 0 -> 24514 bytes text/testfiles/mary.ods | Bin 0 -> 12083 bytes text/testfiles/mary.ppt | Bin 0 -> 86528 bytes text/testfiles/mary.xls | Bin 0 -> 64512 bytes text/xls.py | 45 +++++++++++++++++++++++++++++++++++++ 9 files changed, 124 insertions(+), 4 deletions(-) create mode 100644 text/ppt.py create mode 100644 text/testfiles/mary.odp create mode 100644 text/testfiles/mary.ods create mode 100644 text/testfiles/mary.ppt create mode 100644 text/testfiles/mary.xls create mode 100644 text/xls.py diff --git a/text/README.txt b/text/README.txt index 0fafd24..42b2ad2 100644 --- a/text/README.txt +++ b/text/README.txt @@ -66,3 +66,32 @@ Word Documents 89 >>> u'lamb' in words True + +PowerPoint Presentations +------------------------ + + >>> from cybertools.text.ppt import PptTransform + >>> transform = PptTransform(None) + >>> f = open(os.path.join(testdir, 'mary.ppt')) + >>> result = transform(f) + >>> print log + >>> words = result.split() + >>> len(words) + 102 + >>> u'lamb' in words + True + +Excel Spreadsheets +------------------ + + >>> from cybertools.text.xls import XlsTransform + >>> transform = XlsTransform(None) + >>> f = open(os.path.join(testdir, 'mary.xls')) + >>> result = transform(f) + >>> print log + >>> words = result.split() + >>> len(words) + 89 + >>> u'lamb' in words + True + diff --git a/text/doc.py b/text/doc.py index 3850246..8ea895f 100644 --- a/text/doc.py +++ b/text/doc.py @@ -17,10 +17,9 @@ # """ -Searchable text support for Portable Document Format (PDF) files. +Searchable text support for MS Word (.doc) files. -This uses the pdftotext command from xpdf to perform the extraction. -interface definitions for text transformations. +This uses the wvware command to perform the extraction. Based on code provided by zc.index and TextIndexNG3. diff --git a/text/pdf.py b/text/pdf.py index 55b30cd..41ae286 100644 --- a/text/pdf.py +++ b/text/pdf.py @@ -20,7 +20,6 @@ Searchable text support for Portable Document Format (PDF) files. This uses the pdftotext command from xpdf to perform the extraction. -interface definitions for text transformations. Based on code provided by zc.index and TextIndexNG3. diff --git a/text/ppt.py b/text/ppt.py new file mode 100644 index 0000000..706a657 --- /dev/null +++ b/text/ppt.py @@ -0,0 +1,48 @@ +# +# Copyright (c) 2007 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Searchable text support for Portable Document Format (PDF) files. + +This uses the pdftotext command from xpdf to perform the extraction. +interface definitions for text transformations. + +Based on code provided by zc.index and TextIndexNG3. + +$Id$ +""" + +import os, sys + +from cybertools.text import base +from cybertools.text.html import htmlToText + + +class PptTransform(base.BaseFileTransform): + + extension = ".ppt" + + def extract(self, directory, filename): + if not self.checkAvailable('ppthtml', 'ppthtml is not available'): + return u'' + if sys.platform == 'win32': + html = self.execute('ppthtml "%s" 2> nul:' % filename) + else: + html = self.execute('ppthtml "%s" 2> /dev/null' % filename) + data = htmlToText(html) + return data.decode('ISO8859-15') diff --git a/text/testfiles/mary.odp b/text/testfiles/mary.odp new file mode 100644 index 0000000000000000000000000000000000000000..bfb4809de613f16423faed428e64147dd58c096c GIT binary patch literal 24514 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 VB=BL$H~<`g)a7Rldg>sc{{y{lU#kEB literal 0 HcmV?d00001 diff --git a/text/testfiles/mary.ods b/text/testfiles/mary.ods new file mode 100644 index 0000000000000000000000000000000000000000..eb5137d11be6ba74446712ab844ad1a6636771d5 GIT binary patch literal 12083 zcma)i1z223(=`qu!QEky1b26LcL>hl4DJ>jf&~o(2=49>BtUQp!6CT2yZ?}EHoN=p ze$QKQ=jrLLI$hnjr*7BnqaY0lg%0*4GqI*@fmWPv=^o2Z7u@4zZEg*8bh8B-*xFi| z8yPs7+kohuLB@181`g&9bT+m?kg<)ClQj_JNatW{4>T}#FarV|75;|#2=k}lK9+=S zKqls3`b6J@)+M%b!M%g_r+gXJBLmv;scD*x1t>IoaDk zIpJz;1qr4g4g2If7{t@Zqx`o!*pIFMbjQTX#=sHy%b6$pe>(GTgRr%+b+Ub&2d6&< z@o#qc|I(YSy^X0o(BUt`|2NBj^Yf{*-;?&gS~=R-SpDBtME~NYxwU~Q(1Bja+|k;= z*5UuSPtPBXjch=Uf82{XO<9K-Hst0Dbz9d>N_6sRCz^33I!RL|qYZ^dB6YX`5fz(Z4-u_JIzCFo;r)!_ap+t73AANhT89q#aQM5vfW`GaR zEv8N|Q3C&5$k_)&CV412rgo$^-uvNCR8 zOyqThS&6PLej|=RlvCve!I*Zee6ilkpmS@Aj zIToE()mfV23^y^$0LeJyfwAK*a-S;vdQ*pxutU--*gH+Aix7Y6cU!D9Syqj3K4J|D zpWU(RkYPUdrC7XZxC|j;K+u$%T z4soPya4U>008NraKD*5e$%7s})+T(C@1?3zjvTV0(f*Y_*I0pBrx&GqNtTds2Ww~a z_~>fpofW5VXEvkSQSE{7W>ayGtA_M-m?B-qa!&3$XiG*tNxv2`Y6z!i@DW>DM$q); zhM(3QS(@FWnEMy9Mu%k2?P4=$Nnxn@sOx~3%0ldvEW<~e_Ri2W)jT(|o%OGJyGP7Hf{)$D$ zAl*44(ZVL_Od?MSJ(;C&U7wD_9K+eiC}^}6PV@n~!}x<`V;AxQI`X|}B68y!(Y6|> z1Ag!001F4y<2E{NDJs!Wx6T`uU9mPa0PPayu$GP{xpGOF@IXu7d-1MDtAl3W`c<%=bLuL?HTomE|DZ*nxc)UxB zY-WxuUf5JxMJhyhzCOW#zvz6aZxy^Gy;gRvQT21N^@e?aL-y-QjOh`z<|eL=J??S~ z)l$JJzL9PG+?9@(W9lxMys6)sxzRshEq%29HVM8vZ1HV9{G0}XnRky#N4_frL*e@j z{yQn*O?DV7x|OSA#9nJKwmIdQ`r#vMt&C9USNbZJJxD>7$a@nk>EwX*0RR(16=1Rb_-IBlHG9^4B z7-AQmety;~eNAq9@ky6IyVTEr1YN}7SOyBuZXI}}`K7fl@s%WMYbefF_&lLE3@-)! zYE3^{URYP!gxzW*-Rn_y77V&n3$E|*o0X8ggO(}YNIS=o3Rw$N?nA9V7CLJer550M zHc)djVB|AHaZ}s#`RA_Yz)soEM!-JCliOR+5R!aywc= zkPRO-t~~zF^)|FLP$$-rR%ZH@-MOM%5iV(D$8A_XOh)lTtKZ8Wf2rwVdfQ8dQBMb_ zE|{~AQ^2FJKHf)HdZ%?9FMv^^hL4f0McIT(z9eTpE?PFAre+vEsLH-rS_^QoD6Q-| zcN{jk{|YlZE=T@-NOeMEvAXDEXhWY1#&aeVeZ@G5VN&{i?6tIsd$j_4jG&u4?~2bF za7n>O_6;uvEp`|{c0k%B!5j{<@Xf(O2HlQ~FPI`34fp0&ljOQscmPvne{@`tn(u2> z%!cpf75wWYzJ5i3+z-A0q!P`CRTpU!*QAE@s$L>u4o11yATQW1655b7W4aHMH^$@}7J((wc0iY7H`{fcg<17>1TgDMEtl&3rJ#u*k2dw1T z>b0oqSxn$(l){Nnlx@XQrPiPt!y!J)$ccNrWA5vcb3S536Ow5B;`CkbJ$}KQd|ej? zwM7qtSaMZtp=RNj?d!$hJocuX&fLin`bHI8`uh*@XJ4R0wXm8x79 zuKtMF+&ZX4hIQ^sLG(COP^1ca`<{$}7O{qYxp~d`5E5CuMCR*Ed+srau=0ji{&8yX zc5{_0ombMY@vEKu@u@zXL{z4RVhHn;DI!`@GD6T;l#=0Z4@TWr_=0VtEq7mh)lVUS zUGhV#n@Ggh=1QF4eG}a{+NJ$1@#;Pk@lawl#&Tx<1Ks3v(=XAbV!ZDrc`)K&mz$?Z3$p25f}$g@aI825!59H%%Bm8>g`fBSBM;B&%9i1RXfp*NNvQJ=7gsCi5$aFGINZN-zV6tL_CnrQw!2CqzLUCgf^f)W z#Dyne;6$QQl%88=a^DD-Rzl704dCwaZFy1gmggIn@3H@IO_U%??o4mcw8^tO;krrn zoZ~#Ejefsr23-EPN?4JcaZ(xYTCTz4(D&|{aJg^@5qJi(-hG1fLrxAtN_uxo#CUSsNnL(&=?EAmebx zaMCcwYz4L`upPEIlE#gcF(`7Y29DCPws=Ca8$jV7RUF83gtUKY<9_()m#5AqlzZ(E zZib?xv((OfHp?A0@Ln+PRSi)*I9ZFm1)R^wU`k$TP}-7&Pu;B}G6U7B@jFWYs(U1* zt>!hM}wy@ z&cpxsLF^2)cX-UZcma%b3;<#v$jHXn9AwH1P*oA5nz{Y2yMJSOXon9F4gCn!R!TRh#QaM?Y&^t;|7|yZ|#tM_Vp> zdKVWLIu~X-8+%iFMovyn`X8-;Ke{qD`cu!=$=>RRma!52V~+NeA3D%8(lOHi(tYyq ze|73f_pdJ5*x3Bp(bE`y4)I5KObiSx^gq7?i2sUDQZ3+ba%p&>Z zAJOE0%;irsItDTsbC8oO@!uQt9+Nf;pphdz8wZ0mE18g!xs@?3Cj%oR5B)y?e|BK> zm>550&a}pli6!5okL#+P8CoMZqsJWrAJZR>{-gTuy2gKG=zIz)OtMU@ z%KxzWv-zi$lLOG6));7F4gwkz|CoiRb;b*j1ew?nGXm)UnCt&jjp=_=WB%XNSpHP| z^LO#|ror67(cI{#hmHn@RzO-K8z+z>FMt{Fv-0tsg4M4&M$RXUKNb|%&n5Hg+n=C6 zs{i}V#Z&68V&-IR2r@9Ya-etoRiv{8nU-h(74UW90s~$k`*B10H8#Sa!XO~Fk@xCD zGIRK&?fNscE;7}_yfm=IA%k*(qidU^g%X;&a`xE;jo;6fZtrimjBm`ld>Y!i(Tyvu zrCL({l&7Jg5wL9`;5C2~G<|Ximbl_+%0-Qd=~l{h7@r|O5lz0&Ad2J!lBZSPo}Ii^ zkjCWr97NKIM$0J9NC&1ZC|CwI=TeA^vDS^cz(3si7SC%ClIo&((~HBck69dybIpI@G%Q;{Eau(X$x-@r(=~o?Ge-UZ)62;)>f0vuk@q?3o!Q~b0nlJqfm}! zk|Q_{k^;DvJG+31SL3>p`>Vn(WOlP8`2h0KQsH++@LtX3pW{ue$Br&)+Y7&vv<+BZ z?>XKTt9C9VBP_S-YI*2Of)v8yFDfUiAD(?OR#|^@ux&4u2ME6eqA{PbSxD$hiQiMX zwOLNsyK|4`xO3EUj1NRNdMo+60L&nZQttQN+a$|xAt22Umsiq0%+&N?@#hbalznUJ zn(#eS(_0Aq7RrsQC9yg`IJ1#}B1P93b$@?$vcf{4b$h%NCB6vqHg@}VS8~wCEq;kp zq(8G|S$2?JxI%?_S5FVIJOgbREPB2nU{^tJqecWvCxqAksoj>GdI-UBbs_Vh42z&> z+Z0|(B4jlxna%t56*CxrD`p0H0R>Se=+K(`3?yPeHAAJ0J@pNGA$8Y0FqnUp{*%ju zDwh#~!wbrIG)$|QYAKXcI_qq>&6Iwy=C1Q2?VJ$PvRtZgnR)&rQf^unw&1tgn_Ya4 zvjqJ@&|^FvuObMt;m@2+3kR(26Vpwg9&8C+cy3uGmcNY^hyIu}5`|L)Df`#`g;{?_r#5pq!+PV*IB_{OQBOh!8&`#UN!Ch_n7q_)kv zUFJat_w{EYpG$Fsn=keVGhPcbzeh{4wdyl6jq}RLeJ+4B%QltBWxQm3W><|Oe7^#v zKR`ysx8+)%NjvRe{!jv8Jud}~>T)cHe9L^zqMr)wTp2?v+^*KtA8b#w1;vT+RuF4j zp``q6A&e_5V}!!I!JdeD)Flq$++J*Wopbv5hwEo3N}cDa9TbserIuw;#sEn#s;%UR zW@dLXqHc2oPMKooz$19%nx@Tq&6nl0iGi@C&f*dh&l9*bCvCoUQQle`qE}q86!Btn zg&QtPxe8}aQSN(yNXHMCIy-Ni_rGT2UcH)+si|PR(iA|l$y zvthIutFiVe6zNvE`0^HZ&hUh$31d3mucSYo)mRXZ=#3S=Z4}9Ae*oL2*VZNVi3l|P z9F7;z@w47hPE+QmK=INf19lt$j_t~J&2pnK*PPpg;|f)5#`kOd1t)4f%9w%gAanpD zIqkQv?C8g*X*ZYL1$p5k`)q6`FZ9}v?@(p%_P<{1DwLw%6m!?@+Fi;TR`0EzSxz@b zaWz*k>{v`_E!7mX-;rOv*>J}3kb8mh^?dO)X&3MHeO2`mtne~Ef5S7_68r`0?;2lo zI7{;QVcb5`=Jk}STFO6_8LZzC1Wr#C*Lf>|oJnKpm}kMDWQOpaT8_Jftrd9cX8JDvig%llYInq# zr^>D~>OD$Y|K7btZDz7YTRYR{MFMpP@p>xT!a-ri*rGJW70#qvu+7qC8pL*1K<-d5 zl-?`jG72B}yIhU5S|roFZf;_9Cymi=jks*am}?JM;ez;KXLM7!Es^Yp&Jbg0{|hCE zbc%qKcsjrUy82pokJ|kyH+UWd-hDt!l_>2kG zqG-42Fw58G*#S{xlwwBtdS?2dN%jQNh3o5UyS^KHLT)R|%eHaSQgTUr}g&jh36u`^$v+At^XovkqoXkt53DZ$a107gjmEtLj6gsG+Co-O+5K&c0v1-Z zu#zoC@3lTuv$S#tfsF^&iOmSjZPWWaitlf}$*EGO85<}ZR9%a1s5ML4TjO33xfi-G zNF*F`RJ|r*6e+sODl>ui4>hpl`>q6V{=%|jBwiHcmiX3BI`@5jOhfLyip1!7*@cLM z|2X0OJd!^9-r8U=;fo+<>4@=)S;Ox|hu?Y8Dnx7EqwrTOS*?bs5=Bu4uWDSITgN)N zGbf1dO28zBib5VhecZVM+d$u)mffb>tWFW@JJZo#+;?rsOTj_$-X^8Z+mD{mBh-hu z@4RKylD-_T(_7F)Ke5&x%v8ZLqeRi#2^=u6v2fH@6Mohq(o&rHz_>0Gz&gjF5z4Z3 z3D00wjJbhw_3hat5BYb`w9mM)yye#haMys%AkBvDYX!DoB9{d(6?apf*T_?OrN#q1 zUBwd!(V8P2jT6w=gVh8ob@oYC_(xgVm%fS~Z$4YTwD&}RVf+x7iCGtmGNs-KG+xTR zeXZL5u4S!&ewa{$zrI{F-~U6CM+#d2`fyO~7}_w&a36Xsv!PP~4opD2Ehl(B zw=x#1rF`Xm;5Twm0}*?_N2XYCo4}NOgXVRjtcqxc=dE@yHSe+Y*zK2`BBQs&Lh8dXL?K_s5Q z7-e}G=6Ax!nwY!DSfxpfWiW(j#2jwasWbZImTt61)?@k4%~9kKeY*Y8YV#r}6gKIF zCa^N@q*#j-UV-cI-hJT4~2rVoJ zg(}ofvh1L#w!a``t!-35pxK+ zi1N7i)D;)nEYjE0zItGsn=3WH$jPPaOva7~q_i*S-BZe_zS+6ipHq{Kw&|tOPhky* z33e6W(GHztLRR?^$w<0LiqdO;G(Uv&`c2r>d zdUGz2={{`Z>-gl7#8AO2j+4%PXlvk&8CBbK^SfW;xQ7zw$gEKpY!#K8T62%}CD0gM zMdn8j-!gFUoody1Mxd{#(%y|1AiNwPjHo`s-H1C5jX!$gh@3ePT|b&?ef)tb!_Idn zA0*W{dt)5vM_I;(+Sp+iW|9@H2tbZq zo1nYf8(mWl<$1?;FWoolutH7?<6V4McNZyvHALs<@ASyfg{(*WswF}n3Vp$VI6hFY z-Ylc%eB$Ub>xMlJi>X+|6vz+YN=zecb&?Ya^O*us%}t~gab4k!rvXZ3FwHUK>b1u* z*u~tL?=Meo-xFo~AmbA-7ko`Zzz6Fh(l6@o>^{Fu`sQLQE}a)C7?Mrk6L+6Kx4?2D z=K{}sc4Mq8%#rRpE=%p5amBOi=O~*!RQdr6SMLT+a*n{Rc9@-9Y{}=KMEb^bth5j} zH2GGBcOSdgtmuuH1|Qu@J>9Aa;4i5+kXAN*;m6 zp*8i&nvK4<$mE8FcQr4o^AtUWiu8h@v`D_N_CRLINbwYzrU*;;TzDLis~5DSx~0j+ zBDBn0G-{j+aVM+KtgKs2qNNb(IMv+nsaBE+a#o+~@tsfGtITnG&|oD68HZx~NDE%z zP6iSMlg^2$a9*2iu191oxosyT7L)}fcnQd$;AzBfI#e*!%g7Uzygn7<*~9NDZc!k7 zb^zN@T2WPWVuJPHqT=DLlDz-r?G=uNWQk|%QEaClXSd!YcvQn{;+R$40A62=N%i~a zTI7D3gv`|JUEG#?BNvy-;+9qW@KS4fqh-QKTp#b&mysr(Xrf$)T8W#77jmH9B}A%V z@~$oiWHp_R;;ZxO8K{q^T??}lZ9E%x0IaJMxjhlJSyFs87op;X;$)mCmbvWpqxx5h zoVecjcHA3B7dEVhGBMZ(lAar&tte4@_<0>E{7&f ziqECS(UrO0s6>~nV>QKMCl;r*E?k7~Grz8ygg{yOX*O*=)itVNK3Fh(t|jzLwuH*MUEQOZ|&Mkd9i&Iat7W8YojIM~##A#c4tdPDUr zu;xZK3lYXE3y^7+sWayV^e!8~DRAmFweTd8pC6jC*03MvDeBTfcb^=Fk2n}Q?mu7M znu#RuzD#)y-l(@G=&qXvHD1KgH<}Omrl|uoSi~X3-^0;^A3gaJvJD*)E8p!6$ zGz?Y*9dbCFk98pPCG%oPKvR22rQ( zKS+2B>Go~U1i!^`_n6^&rz!2x0Cf&21sN+pf1*&n9+`SYp*YD>r>z0c3@ejKf0h)6qm zqJe=;JzoF)2Jgkw(JIjK=>_VK!__@a9pz;%>=ypd?OS`1LPf5%;g!mt;PdMh_*C{s z*hVBioRU#Od*4Y??wVPJs^=wy@rRN*@~P@pXF7m4Ot>v918u5J1$s7cd#SB~5OeEe9^%B=-i%O^3q? zSDY}dI!xR?3EJ{6Vbofdk| zX6KeJmQ=AC4M0iJVXwSYqm~Luu;kkbP`AiKav_SEC#P{Kvy-0 z*`?$USNf8qFeI>F#1$t9r3mQ=#THi1{>7yN%+~ zF=&uO;3puHgD5?GcWqq`LSud3`Ch)^AHnxok9g3WuNO9EgMUq|?=7u*Si8bZ?vd~b!>lIB!BT5GHFmr> zy*{SS3k)zVk;M~EXXg4eG9$13g0-BEr-lU^IU(su3!bk`@HIc9u)p0JhPT?2A*wme znQ1v{HF`Lg93?$u&^-%MuZwg(m@bK)C%}!~D*Cw6=)0#)NW2n1qf{Y#?LHZv*?0hR zfZG;ULc1PmV~}S(JYTLHf2{6oSu9HkxI1gwS$W@Ej+<0JU01rl!B)Z0RLN84xIm9KZ5F;LUN#_fs&)$ZGD`YjA%a=Z6t`POe)_CPP~&33{?fIKi$?LrNDIeZ=lw z@g$;-jyNJfELlwtYt}vTbz7O=AfeEUaG)wiZ~&e~@*56hqV&ql)*9n!;b*#-uEDdo zpO5#YHOLR}3|91>&J2aKjz-O(z`%fy+`<2jP#BL9N>)@wkXBMojNaM+WNrd<_`!v& ziI=wc!hkGr!5cU{uQsE~Xa_-i3bh4JaXf{x8Ek?cGoy~UI?5K8tHF&RaS$PfYhLkP zTX~Nm=DZY5elRQl8|8u}yYsTqo$lw5@nZvnwk`0`nbGvV9sJZUa@m_&NZAEW`q5fy zB}kj@Wig`Ndy`jt##($TScmBd6K;k)Dp)w@xE6d+yHEl8)ev9Z`cik2vx*wjSkM7N z^4cPpSUvB;3m^|`(Uf``Q|c&f<`LXwjuM~qN*gYU;DrDW)6sDUGNP1nu=7&a4KZCX zP+oLF8j-jjk_399DUo=d8i`Q3j3{q+F77r{!c1a{kzEx|3#Dg9a!)U$AxMF?KT>Ro z={&zr_>yYh#oJ$?Zqr_s_Aoi{*&!4O#@xABG-#Ue;~Cp@1f;dZvH27f`&Wdty7Hcs zhfW7`tmE#w`dg@{n=k+)Ya#>=2Brx6bQ8cK(82zjF#B|*`&)j|Xa8ySTLTR2iB0-j zR33}}WTgI;Ap5iTzcPS+v0R@hvcDz#vG`A%{~*l%U(P+9Uj3Gp$KpRhf750EJ~6+o z{y9XP$Eo}$%3tZT|BdrRp#3e1|AzB7I_-ZW{e4_v|AO?JUi-hIwEYXpZ@TS&qdXCA zf6K+cp!|RI+n->+R>5BxVowCz-@@{^IE;SNaev+EUxt5WBs>wweoM*YQvXdS`(^jk z{zQiUCtu;WoioBCXZ-PK{fWKs%j#Eef8A~Ueg4Hz{`-vdpD2Hgh)+AS-vUSe_kG$w kE&uv6eu|jCrI7MJ;-`W%G|ZD4(&OL$BRPYf`sv&M10p2W0{{R3 literal 0 HcmV?d00001 diff --git a/text/testfiles/mary.ppt b/text/testfiles/mary.ppt new file mode 100644 index 0000000000000000000000000000000000000000..ee3f01facf07e10c27bcba39191c270599e45124 GIT binary patch literal 86528 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 literal 0 HcmV?d00001 diff --git a/text/xls.py b/text/xls.py new file mode 100644 index 0000000..31dad60 --- /dev/null +++ b/text/xls.py @@ -0,0 +1,45 @@ +# +# Copyright (c) 2007 Helmut Merz helmutm@cy55.de +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +""" +Searchable text support for MS Excel (.xls) files. + +This uses the xls2csv command to perform the extraction. + +Based on code provided by zc.index and TextIndexNG3. + +$Id$ +""" + +import os, sys + +from cybertools.text import base + + +class XlsTransform(base.BaseFileTransform): + + extension = ".xls" + + def extract(self, directory, filename): + if not self.checkAvailable('xls2csv', 'xls2csv is not available'): + return u'' + if sys.platform == 'win32': + data = self.execute('xls2csv -d 8859-1 -q 0 "%s" 2> nul:' % filename) + else: + data = self.execute('xls2csv -d 8859-1 -q 0 "%s" 2> /dev/null' % filename) + return data.decode('ISO8859-1')