From 1565a04b3aebd8179cc6bd2e6d4bfc18bad04d96 Mon Sep 17 00:00:00 2001 From: Jonathan Bernard Date: Sat, 6 Nov 2010 16:24:29 -0500 Subject: [PATCH] Added color, better nailgun support, new argument processing model, base commands. ConsoleColor Added to support for terminal colors by using ANSI escape codes. Basically cross-platform (as close as we're going to get with Java's API) TwitterCLI Added colored output and configurable settings controlling it. Created a specific Nailgun entry-point. When using Nailgun the Twitter object is cached in the JVM so that it doesn't need to be recreated each time a call is made. This also means that settings changed from the command line persist until the Nailgun server is reset. Added functionality to wrap the status nicely to a set width (used for printing timelines). Arguments are not processed internally as a Queue, so each command/option is popped off the queue before it is processed. Added and updated base commands: help - not implemented, will be used to display online help about a command. post - Basic implementation added. It checks the length of the status, and asks for confirmation from the user before posting. reconfigure - If a Nailgun server is being used, it is useful to be able to reconfigure the client without restarting the nailgun server. This scraps the current instance cached by the ng server and creates a fresh instance. set - Allows the user to set a configurable value on the command line. So far, only the following configurable values are available: terminalWidth - integer, used for calculating text wrapping. colored - boolean, enables or disables colored output. show - not implemented, will be used to show various information --- lib/compile/jar/nailgun-0.7.1.jar | Bin 0 -> 25685 bytes lib/runtime/jar/nailgun-0.7.1.jar | Bin 0 -> 25685 bytes project.properties | 4 +- src/com/jdbernard/twitter/ConsoleColor.java | 58 +++++ src/com/jdbernard/twitter/TwitterCLI.groovy | 246 +++++++++++++++----- 5 files changed, 250 insertions(+), 58 deletions(-) create mode 100644 lib/compile/jar/nailgun-0.7.1.jar create mode 100644 lib/runtime/jar/nailgun-0.7.1.jar create mode 100644 src/com/jdbernard/twitter/ConsoleColor.java diff --git a/lib/compile/jar/nailgun-0.7.1.jar b/lib/compile/jar/nailgun-0.7.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..05cbbaf44f160c8aa09aec95da105e10a120601f GIT binary patch literal 25685 zcmb5VV{~TCx-}ekY}>YN+fF*RbI0n~wrxA zYt&j}Uh|$;U9%KrK*6Aa{`zG#i!lGA^Un*^*IiCbRftYXUYtSkpTi)5GQWoP0|`ck z{x#*Rq5jWdazgS_;$kYQ^m5{IWA*R>jEFyWyQH@B3*oy6vA?mKFv7RRwPiHouYuJZ z)mXTDIXZv-{v{T}XZeJI934*6>fe`<@u$ew&^oEA&;nLMt6tz2Zh4@;iap)j_g=qQqwO0EDUSd^o?EbOtd#2tD4P{w~P z90(}+-`)@GYvIQBw*QwAf4$mYBWw+w0G5V!&h};iH$x}W|1l%w-=2y4|1-nR(9*`- z#qPgmLjGelPpiykQXoJ;tY1r^_?wwRHkO9Y^u{)Z&dxr{<973csCQI#Ty{2O$u#g*bSD?S!Yj@j~Jz*8_;|0jbyb8H2WkEr+gh>t!qxtigqDlYGk;E3k%}d*8mnHX1L; zMe@Kik(`&<{zSl9f~J7^^PN4!qw@Or}h z?e<2BgdYtP*3veQ%?^bg0hgiOdFmL+JrS$$>20oYV%PN&K~& zH9RF)sG~J>ur9QISnG2o_%$EAEpR+Kx5hWTsO|mTLO1b9!!()={8@El7#t02qP$GR zSd+`KXGzjqf}@=#BZEFWZ(hs80N-3yH=x7_iw4#sqjTv-_GiA2X zT3-w8*tFHOilvAmIlkOD#*6$0&)Q<+DF~x`mpM0QVy;@*CUG&P4zAT@Y!>3~fpI=> zIGB*nqTvU=ry%t`ad=@FVotx-TW;YdI+F-$Zcn1oz{R+0k*{~gqS z#RhShs>}Ts5|zH_fc}4jMma+}LvvH7{{UsQx|R-#2Bt4UkSuOYff88L+6*-WNKpqg zwbH^D1-Gwo=cgwyo;PQlxx({;AyUljIYlc{?2zQBu{; zspZ;h`&s8G>*Id=+7IYtD3&|nWd5cs2K#}oFxwZd!(|~~AshC@9oCC@rP7$-sqzw( zdzH6lH{4W`sM=6b0`!fTvuub6Z~V3>18>d|QzEH<))Tk?){{5b@X=Yge-tujsUCj1 zY+of}cNH>61t#B6RDy;%g0xadoUvlb_z^QSf43=y^KD@-N|Hw)ytS7&af6hX$*lgs#C0kB8%6#pBdH#K|r^ z)nl6Af%;e2h}k^XzcZvOuMcT4xvR zXWfIOP8W&uQxL2J4ydP!rtxThjkh6(?EPKL5sa zU5WMv?sWgGU|}dof6Mx86e{dI3$2^oTy}2%EMu=D`Y|W@Ey!@cdyrwXg2l=x=(p#r z@sUpR71c=$F8#i7SZj=L?H!EV)OaCs5_C*PV`=8Ys=&r-E1pKUwL5At%MLmFE?LVr z5W|@(y|?I|teum$@LP*F_`~lnKlVj*4K&-+;__>FXf|PoC0^3@QM|`)vG~n@XnXh0 zcn%j;W_>?ciLiyO_xJ!-X}ik1yljS1ccpg?DY=_r?n|tXYACYkR%P-Yyk(=OqufQ3 zkUk@c8Gi}c*YO^{<*RY{_(21E%X20JBNJ6#lmhPOaL_d2UYv3ttXypN?yAq{V%J|l z7lPJEPemOSU|SBL#f$ecUIZm3i4&P?hLIP4>QIHIa)P~7>+r1!tn%)qNk?{)d;}M9 z?mTOM%Nn!hJM~O}v?>-kh<2tI5oJQaLVxXSf^529;->a&Zhd$yEk0LHIfaST&`yvW zXf(&Mb3t?cxprq|svHRm z`WKFZ;uWo5y`oh)S(56Qzt_gikiDY{k|3WL?gl~PZ@%^*08#_H6;B|sgw~q(x75|A zb@f5Ja1$Bl>K)bWLM3;yY*Vs4nWQ@jx)w<85uHQ%#e)!vAT7md(fa^s_>~eV2!POw zPgxG3^DK{=S%EYnJs(wMgCEbCc0`2!x}E0>u(%)OiCCUi+R=l>%(X}pa#=A7;U*K@ zk|Q2l|9sgeTK;)ip%!QI38gR%F|wX|kiMvoL;)m!u;!V0Ra*>1gBF&anrKps#=PP{ z1~GOmk~=7OxO=;T9D|6UTl`5sYYxSGGmC|hq}xki1Jb)%`0tsaDq6sDx2#@53OkZ`4c)IrN_WhM+{=wjTq(u7Uw?!}jLmnj{w zGwO4qmW>MqsLL)-pz@yLg9C_f9TVnqpb1f|vV^|%!y>aCriE7?%n7QgRInRH3Q*7J zUqA}Be#^rddz{Q`EKy#^W{o#Q`Q);OHgGl40BVe(Ro&G9`>n^8^tM#ljraT8ztX2E zSFq$aU?3p-uSWAX^eJm^XRZdYwE5>BI?tp1GCu?a1Rn%2J%l=hzB&Y>fr)|njobK zf{8(ITY!p&tvyJ{-#-|5kJOA10viH=^(~GJvIxtcwQ|W7Vkp`GJWFr{JoyQP+7x)s zmAke9tTYZhE{1}x1`H?4gGmRHgF(m%!!WNt`%ZYTiu&$%`@ zDRpy^7IGf0|ClJ9r8;IT=zwwH9rCg;2s+TeeovZ~B9n1YARy&$KtObV^F8GyMC|RH z0fu&f|CC6odd_R=hS>*guJxQ=sT2 zqe$o8nm?I5Y!k4uEX~%2rye9+equmUf@vW9EKx6G1=xKmGHeGk(>%XHGue62$Vj8T=yD*nwGySd(U0hX? zz;=Tp(q^yLY^1dn-|Wp_T*7rv!*nOFwMnN2BTZLqpL!oLwrFZ3WMyrvu0*4yr_v5e zffjPe#I+PO;ovBHVfkjKzA10+B1UiNne0`Bg+7cwsLVY+J|Gv84CO30%bX?6NZTcD zdFYGON`4tpJA8&)DPNMaYRkHY!W!SjItm{^2 z*UGULvd;!L-W=PR3pcz`7iCsC+swXjsiEgq4$6;|9-1It=WgT?D_g5&p0;hJEqBc? zLWo_-I5GB=FSR6u9zrwA5g8^IkJ@@x-5vMin(PAzIZD>Oyd|~1V=4bmX7j>bZr!Mj z)m7=TTV;(Go0BW%Qt}0f4Jvn+$WJL{vDWW#nFol#{I{~wW zbk{mOh{54|fInym4{Bmom=wIResyN7+;FiKO16?XunSZuBN=YK5Xo$9g(XGfnuR?G zzLdpY8j*fWRA36$?S1$Vi8s%g?QzOCH6kMesYRDfL8S$doJSBA;2Z@{j%7Mkqt&eplquQPr7q=JlEuEJ3_;QaA#EGurnFy{Fs zQpLVR>ff>KKUe`^>JIo%g=(vUqlW6s?r)=s9wbPK_C1A~6-=h8SslER3Jy_@2-(86 za*3>+7G~6Lqic6CRbY?c1Vdl}O9n4{Hg@Wz5O;cWG6a=gK7BW9^PTs2!}-d?F2V2j z=cfXY^NUhH7`2Z(7EYfHw6jKx$3pgeL*2-1bsiin;V2^0mChM3A=D|86ok^>hF=X=XBH{6i}xN)(b^Y%n@o8ELX zU+XBZ9gCm7KYD_O?w_DT#vGc2(PbYlv;xWLrf(OJQ|JNoJ-As zNqAd%`w1IL$xzt!VjtVmF4>}>=}w;`sx*4FP4OB-WwDa|j`fe82hAy_%b$x*PL<=y zKO~T-Z?Q{MRN@jYxdA(#UJvf;PnyXcTk!#DmjDb!Kt^>U$evwfMmS5Xl_c#-%%uIC zwb>E9OY6x}S^#kFt*{2oK9(f|u`rpHJ2zi?f#!^bAyWlMHkXcrV8c(z!gMSx9g?Jz zt@J5z+EpuI)Qbz6wzT+Z9UE@RqMFm3IE7fgGa7;@Pg;`n=DY_KvW$d)^ohu56;bjk z*Y- zd_LiqUHE)VNqK;lxLoeQluXU~26LrXqzg}5V*jkuVpXU$x0AchFpay~u(i8hsJ|3m z>P<)t2UD>zcB+dBV<8F61nt(GqZp8LT7j$j{ovf)(OF@!QMn>j(*5~sbh8Uu4m?38 z48t*p`p=t`7$4o``hbE6P`pq=Dmg$lOl1piCIK3JW!0!{>eWJVoqqol-0)$@XtZYs zS3fL*r~HGH$eu$+!QOdor}UorF_Gy-0(&POJIk1wBr$*O(@n=i_+zV5{3k; zIi|<9J(3j`kLXSIxOWWv^Q*FOML_u+7i7U=@@0AQCY+jPxf@v zg|y6d?Ey(3=^U!P3&q-HlB^VN3&Ck|qqvo);Bqrc-B{bp1dTGyR*RPD?qZwEgKmNK z@#fWByT=ie)HXZH1KCn+nj#6`U=SgwLIy1FDDzFxL{B0osKOhpH~US5qUBC47_XQ` zvUkRBsf!2SmM~vMT~i83KJ;`20u^TXk$&UbjqD{7)$I6q&kTi*Mpk$={vv)Y!uy@i+sOc( zn;P;gwhQwjiH;vx(GebN>dxCIAfzAiEdD}AJLbSfea#M?aA%~jcB5SSR{u1@3S0^i z!-VOWGQHcmFql7$J<5Iy`5QG?YG(_Qem4e8oy5JFWf#yf%pZV)GK?9qrYoYAkbiv4 z{^22!o*4Gcf!ix;*SN^HuZIA$Jr~<24r4d0hgWcpiSBj#=i5OX&+bpTk}+x-WT zsm1n6gEAq8{INN&S!xarAatKovF-H$8kC_TMx|2iL||Gvv1=$&S|2_u-x0dzPfA-c zIt4RhzMq_)@c!fN4ZCgRCIL?A=VgX&0x@O@=rg*)PwHZ3oiXfe*#%24l(&*jp zOe=C&#^Qa%L2hf=WF+tCfy5TNtATny+d?`FKZo0~f^s6IqdYog&93r(vb{>hTopN5 znZJJCEBoFnTQO#B4JKcmiKs!Fi|Sz=NmYN_v>1f4(1$f^h3Ke!qcyT7*#|mzb&G6t zyG*o)Y`q1`bXWA=Y!>a;GW(PwsjmG2@~?XEj-+~u`AZLag98CE{OxCxvU6|&r~sTy z4Q>CqX{I8hGOvjG+ios{T-;mGLvvwFWF56UVh>ai7^(6_G)stGJVUrhj+^M^1$e5> z6_CHrc@`3ElNR3>R_OI7&`*qy0xqJjt?hWj>&k8Fb86rB{q_{*hy2Fe%#WxDPe2{# zKtZCIdcPsAp`)q@Mhq2aO`c9*2nth{iBH6!B|0Cr>H~9&LO)j4;>aJ$NN4X04aPhJ zMT7As(<3?s!3<2qIJ#Cs!YjzK95rU!Vb_uq?{J4Mz|AxyYl-+(Cc;G3rJ1w5#}vUM z-#G1Kkv)tk#AYX1UObT>6D&>Xi#U!at7Wp!x{DbVYx}y`z5Xn8jWfu)bO{Fww+4Mj zj{PAhjZ&BcuD^wq(GMZ$Q(gM(`Ff0Zz=gQ51k2Njg=k{TJ*KjQkOZ_PdPsmF9)^%_ z^RH9=_etSA{yKCyb7~nZ#SBpA;DAHN8+8AdG?x7~gzN*GIK4SP-4=NY7u`NnbQ12G z9cts+Qwx!ffOBrUosyVOi&>_KOpsHl)}-Q2?{$FLX274BhpH-(aD_>()yn>JD~g#W z@!J5s2fFK8o>B6aTRH1){?)-W?;+lGc7kt_=46E9V&)=LPmD)=!dJYSs?(9{MY}ly6uN(a61Sue#E+o0hmRP4=xK*>*A7A+?Q){5ZHqi)eMZMA; zh4;M@pkpaUDUggFZ6f)hX#lFMwx{Ib&))F%0oTI34ed%lvP+)wy|*S9t{#5JK(iTp z4p%0jl2Yi8&1Lq}O?HVDvTCaKDIMxwEksC7wEt;o$dqG)Y@c)6jdHNK-WPxD@o#ZVQ;Dk?s%S%>!rK-)><3HT-%dWGzO& z7;E)wznbxH!%x8l@bB@bv@X9ch{%V-Q*SIw6(=Z?fW8J26Li06-562|hqIkJ} z(OfZ&U%_r8RBk=O`t2U5u&8jI=8~5$-t)1T$ctKc-C=?wwXmR5d-U7KIgnk&npcBP zTH^e*3X{o8m=Em^^X8KHqQcaGipGeRBLt2QKB~Sv!yV9KE;KP5)S5Wc{-HcL7(Di$ zaZHRR`y~9UFHwe|B<$k5jBPlEo0a#H(D7;s0D;4l=IjCl@T`g`04qh1hBiI)Gl9mfF{4Ik$+o@!9zVXIHLn?quVDz85E zBc%z(UaDrUkyHV(WV1oN+fvv|_SA0q(vs}CB{6cKd~NfsxxMC4LEX2_IOBH& zk}~CVGoG9J23_}rw}Y%9U`b%Y2aZ3ZF85qhFX$uu(Dm0uksrgq{h{1XzZA!=z9e@p zarV8>=GvZ^{{H2jQy?_^Q)H@oU4!pfIz?k+<5r96!xPJ9=NK@1WBzi z5*eOzTggs$%s2NDMgbwQVUi@wjFe@L_YDNwD~PSk8@}h@Q>XRQoVKHJj62**6&c)6 zfWB5xQEee@Xhh7gd!J&LjnVui)LFb6E|aSOY~_69hYL7t@gIEz5yL$kLX4jQxZ^mF zesW|ov8Ma*dK%1en!RZzd{z&F&JO^T1$->Y#;m3!BkU$97*_PtZ4e}=2yJ7?B@17n zJ=nY9qGzVY7*Zd>##^j#7!y-Ugt(8e1t1My!miDqKh_G!4sp+fJi;cPHG^Pd#Hbzf zH_{}Xfi5o)w8BS=+cq}B7DyV{1YLv7AT?uVd8L>msPT%Ke()2kR^?%%43<&G@eNP( zB5DW_u?5`V{5RbGs!_DRT1cRL!AxH-9+I+4mtsF?oMQL%6VnAp47{a49C zWm5Scl3+fAT~u2~Fh4?xx=b!LrW z6F0p#(D(jl#c4QItvU-cr{903+Xejm{s8BNuz_mnP8eXP!cG_q`5QqGf7hX6IB!en zC9Wwk#A*vUkI<4XEZPr=VeW5_`}WRjpjp%UQM2g+a>`Bouszz1;-JG>vm74u`C&=Y z;w6fIUgL0R93t((oGP72)V|xw6^JexV9-9t8b6#Bj!S=1mR4poI6$|-UQUx~c-z%@ zy^=%1{ge{N3t5nJa5))>el4|(!F`q17O57}yxiw;?kMx7KE5Aw1EJoAG1{_?vE*pZ zHonH|P)x(UFJ>bL3c&ivp6%`rXMR%xQxRcnVfsGQK*lCsa+8A_{ zLfE;>WjG=dvhfH1`z82>B})>y)JPnDtE4mCb;YgO#*HZ{7#o&?TPhKnXV!C4ZwoVL zaupLK*>wV5bh2R!zP0YQFH)N@JE_`SF&)MfBFhQiphuE>i>?5gazYylgZ4cMR3tsK z48=&CA`UsVkRLvH!UUokslHUhVy%JN6L|O;w15AL9ToeLJnVK{y7)_ai~eU+5PLw$ z4diHS8pDygKt5yO0>_C6sT)5d`^WuxuJ0RUdM8ug0-}lpK5{xV@W0$ zT;KeILyF-C_`jk}*QvJ@0uBgh76%B3`hSVG|4^INnoyd$i)gU3P&dQN3?^utDhy`yzsXT4u>J#RE_I!|X~{JCH71!@N5#%NzGI|%l(aFg$9 z;c>ak4y0bFZ_Ibdm*SA`;d0lI`?X>h9o$R19N4}zI9(JhzwURRv40Z^|DmM* zljvSQ#nyCMPz+B}1HyKjW%UnPAf3vur|w z#f7?53&iZ4HT39ARp_2IgW-ULwPImbUcw5H6ax?Yequ3nfKk^Y0o<#`UxBVmlGO}y z2GEuqwrG-+2#QIL-4|UmVnFtb3_5iupu3%gYB&z(hkmmt7pFjq$dI>hA=asubk?x1 z+FUi$K?+c^XVJ%EFI1wDzDc{hWp)q>Z+qZNP!pFS%-&(0&3EGUvWueWR~ZbUR6 z!;M#OYc^2PIH}myxLl)?Gc+zNGvTnZx->9w5`icEN#3|lENk1!J+b8=OKFv%m^MRe zvzF~*6_I+}*gP9&T?m~$3ciGo^qpj48G1t_UGX%|chDZyJG+#QOpo0% z6FTNUGv`(4hPbxMdCPNKx+c%UZym#|nq*00eC&vgAtl}#tFZRj1Lb??gCdmf<>YOe z=dD{y4^WPx>R7oV!j01mB1E&ogi7a}Ky&lZVC%+v*xHtQT-vsJvi{soCCbER~qn`!noXM$5BUuw_qeqaDqE7l2vGYw|emw#KDoKSQNR#UbsCV)z>WcCn3Pe{WGkSwGz&laA9$8krj6SEqK<&g=Q(DtEC zUt4&75U~{lFZIw_1oTU2dG-;+ZpXFYr?5CjgDVW|PpPTZN!`a2^ozL@^+3DAbtoC~ z0*%8Jaz)jj{dqj6^q>lozT0xoH)0ug%B+s|YMid%hS1-~(6Wrwi~4OEIn}O;550?3 zD}k7^t=eaCndIs5xbA}5Et@-AI~F5us@H6X<|;lfR10!!?d!Fg+2mQXYg{R(SW$cfV! zr}%7|if2|`()JnCB%K~6v1gp=k&U*dcyt+IBg$X6)({O^(c1 z7o)&8n#6Fxjx5z>B(Y}#zV)jT|6Py)*RcASx?1@7oQXs!QeeB3 zx&gcR^nSD;TavZ0bhu&taFEH@IoCIq4sS5$P%z5q_yH^QERstq*LqfUPzggNWVFhI zHmQ?HnSczd{9K+P*(OVKQ{&aBrIn&~f-R=eG>HZ!wPWu=ygy};1ejlhzqF3rDZZVk zkGIJP3R1&}ntU`8++ZRWJ-FRbJ#Cu-dV9~v*NW1+<9!kVJNQ+uzfEzA6?*&F$aj^J zTfh$W=o!v9mzUN3`rCrN82@RH%J)Iuy_Dcxiq}eTt`7uO2#7eGJYNg{EZ-Nf1E?9$ z9Nz<&UPMN&It-OJr5+0_0cb3=$3jiY`LEop!VJ#f4Zk_wrg41JjKy9!YWXv_C0}^^ zZb3ZpKOa&I(6Y?{w0d0 zENoETC=18n>Vx!?i1%U+1}jo*t0!^9Z-LAY-N!hk5ntTt_4p=C=KF}Mmj38?bRgw+ zB-b}3MOHUNG&%(Xc>?llv@$4Z3vz-DlEE3T#8+prbmWI=#52#oJxkTUaY2KRL)@> z_n@?=BSUALF>CwGd?`j5=gerab3`$PiLL@M3_mAQ`vY}{FyMNp<27gU9_&@$u0?*- zA*cnFWcZYk%O7gvFCdOr!g*GV@jAxPu%vh-bPUup8ftFmYg8oLZk_EiU;9(nR|DbH z#Xql&oVLy`1`#A`foQg@lWiwO39!`_a2tOo%-7qJKTt=wj^~|B%=VUB>}UIy<{*n3 z`L=_^p%AmrIXz!yTQ#*BIfy*Hk8-QK5vrSGX||V8l946oOc;Z*$Ek#c^AN^2wxPwW z`~(rWC78|;Q+(mZekFHUk~jP~FSS={+PR=}edgEy9rOu@dxQfWP0sTVLRgNP~$6YeZJqCsbvm${aR7<|aIjHE_l^ zvqF-{6!^&sP6jU-SG$pRwg05(06NSQqn3WNiMPA_;+|HzG2 zRTlx9h$hXz9x!X&rievSZ2&N9{p*!R{+o6(lGP<)Y7S8q%1?Ws^LIyC0%;W%u0G}; zEFRj(N4`lEPJ2}$L3fkUYPivGKA~G@B0|OiV*BZhl{um6Xv16;$XC1lthx6tiQLD> zG~PtHAH%ElJ4sQcw6#iT5NX3|4Hm|@$Iy0;x8xZ1W?7se9+*9Z4DlB^qxAEb#}H3m z_yO!;_fLwT%L}IdpFFd;BU-8eUtA1Ur5O<+`$^wxdfDnxt%2bFM#_^*5iUR3>gfHx zZ*jFpt5N}7ra8yGQfy(7*khf{5Ac1u>_JQD?U-vBAv0UbEI=|&zL0pjz}%5P_aN&Z zF)(a*d#gD6#5Q@u`eXXzNw!(SWI_<*U1m9rvWB~cy<|F{3jx?I@J3z)oxK|aHrx4b zFME>ETSNf}eHsAE+`DVj4?O@^Aad=6lbBPgb1^Azv>|V;Zl}T+`}--?lzHyQUCIqs z%wA7eeIMXadT;Pb(gh*&ZQ55`rFooT|+p{ z%t7k2-j~_X>yMlF_Ca|nfhTGYGq#!|-j(_dFgStgZa*Kj^bHYOhoe0r$xB__JF2&+ z*i7bYSzIjCYg=4YoC4%)QQZc^fl9;Y{M>s~z;s3D6BiKzI z@|7B6jSjD_cEaLQx-Gv7eIf?rj zAa2MkbCqvQ(aep01=Lc$R75o1vZ0ONK7RR1O3}Pk2Bp1aAf_o_S|ZfFB_O6NUg*0^ z_ugOpBM9~+m_O>{a>MYap< zNe;k?7@%LPEk1cpKlMilP(PS{2!u}vj9dCC-D-Tu4Q}5eVEtC<{iUiK=tuJsi+P(6 z@TcNra9l{=Tl|K9EC`X%Xnk~;SGB;1=k*nnTCF@P2?*ST4wEo>Q|J)d(i>L|tW0@G zjkyedhBjCjdXhY;Sk^1m5=H*}qA^4}1a>_fXEbT?ItsI8HGy?6+#k?T?B%m?Xib(> zI-yE!N5-M09x&s+VVgM7xtv?~=87zw%@d_3F4HFo-(+*KY52s|SwcR!DW9|~7s@!k zFPR}9$w8KBtUgCNlN>bW&U}bD%HPPtw?MNt4}l(seb8u}eTAgv5#vge4G1bW8VRE) zy!9{IEwW8PSyRsw^Xiig5@K^>6d4$;F6uQv6Wjid3;qm0)rY$&S1Q`HWPhm6U zJ7arK6Gyql%j_V8UAThIelEA_RBhX}wA-lhV!6>1+Q9!I$jeDvKVvZeSgXd&M3ICm z$xdTSAWaG~?H-VK_LF}>iyPm&aPUFWP%RBL4l%aFZ;~Tf`f^CFWHxV8|w*lMF+=zEd^+&rmhO~}s$ZZsQbmktx%m&l; z~d!%JW18S;A5^DHbMLAkj!hvT>(d zVR@!`x|%m(Cyur&y^&Ea|bfI9X&0c{`O5YXKKD3*!0(v*~s!F5)XtW3s0#~7AVnF6KA0$G>cTG=f5&!oxi zr!iRrghQFw5FLj`@l>Ux#G{q81FKN+Ov^~|ROhr=b){42v)MLzyZIC9pW21i2Pf8+ z9pVsn6j{1y^s|6%gVa-4?O>=w0;fm!%9B|cALv0==2PO}H#Y1%q3Au*LtE(>+b0T6 zFV5d?Op?SVjfMzmQ>w@_@N4PMogKkU&Eip8LFGyTEhs6PPlAz5HV<$abnqH2s*&*k z?WL<23}`H5nFJF{R$3vB(xn3z7IhwEHwf$Y9iCIw>YyVRTGg34GAWgnLd3wN5P2PJEfPESL`PtO~3{@&5IjC#hVz#9&jdT+234H>)8~#Xs=!g#W%Y3%4TYk^}(#6A5_5|-I|=>i76=81hz6aWO_%BP{oCgEWHIE zB;p&R>)dLquSTY$^U5yz`rPK$y&wdP0=fVpD_=AjDp?J~9AuR?;)n>B^SSV#6O64E zZ7^JvVtE>_y5RHg5zkNSOL025gVF2iZVUE^$*tA&z8Grqi}JN;DVX&uQI#~$_~pkM zA;=0t6Pq~iShWrkKHmsZrJqZjz+LRx3JWQ3*mn2sKkS^G&@!9#v<}#LpFTNX74N)F zxNYmxCWRD%YTO$PirM^hCeofob#01E$j72~4OvDtS@Dij=sOXMEV$HvhiDH8&%Y0-36i>t(p?(Ri8Loakn@4Ozm^mI4Q$rGsv8Rp<;2g6)>h1y#PZ-#efb}HJ* z3`DD@#vcG0!SmmYyW64Lwc>BW@0h=KOd*faUHToxZaqqIQ_FiOS&o+40?fCXN>_AA z;_JkfH#>QnJr}%u+QGvJVzLMtwO|FBq5yqJDOr?$)V^KAeOQH@>hyg5yS8EtRU^2i z={j2n(!{!|U||~k8!*Y!-^Fsk&`TZmnpZ)oMpubBYJ-BtXfKy$;)tje;}g7S__aDn z9ZNw9e!s-tk7Br`OG;m5K>xv-X0N3zHY;kxr_Y(}t72r$q+P$Qy7N@dIw+n((V_FA zSZ^Y?V*yE-tV@kFQVMNmGggWH5I%9YzQ3hClUa8(2QVup;|gb))rRok5FEGm$j1cT zM1geX&kMEvh>^)3z}7RpuQzh0--E)S>C-d{qE(dr${k{w8qR zWvTBb#Q21)2I*5N66pdWua{z*XXAd9B6j_bB4+(g!wO07n3h%47OSyKYU!a>$ z=&f)gk&r=dKvySAmLxY6OC9bXc2{IdW50S#;r1!5^FS4Yz_7^?FR(&Afex9Mu%+Si z3W(f+lHsBoHU^@M%g#=HI}KqMD;yX3Rqu`NcVQR8e!bRR2{ffP>xDnA^vrSOt=k?R z^Q|QEybB*u?z&nAelNO~@K8A3-*ViTHc}^vgaNSO+c^bWYW@(L=nnJOIfx+c#JC=Z z;>qRu*vQ!%JN49km>7j(3(vYL>7NXRH);t}Rt$Wd;3a_BToQR}$tn}Vha$HwV_~on zU_I5?2u{R_HOQxMlZWWN>b%l6KRR))xs$_(lmijo2erwcf@U~G35=4U8MieZ*P(zL z$yYMUhjnh#TNB(*8^20hUVSkc?d<9IuYsDlwww?q7!I(r!w~;K;SAqwq*UhiAKc*L zQWi)0Jq3N@PtsP~P8GRUk`TywxM7gk;5{92*WQ~+0595PrnjFAMSD8iJTvFGAVzI9 zcI{ROWU>FN8N|S@Gy4z3fnTC$x&AGo{G*}u(TR_z*yF2KR!c!c$sIoJ%=kk@LdF=a z{4$Ld_2+scq`A^BHUX^iFG#(lb4Shy8F*|vj{`OeIV*H7{ zP9{-&k;)pgdMnstnbghJh^`V7M}J&z!=eDd#n0%<=+Bwtkg2!ZoN^gV8|E{eELjob+OikfmrtA9M_f3W}NDC%dqqhd6$k zNSU@>*|UR?`^w17JJ6G(kjIq~xOa<0{5$xcNyDaEx+S5!O$B!5&geSs{>u!@mC_H2 ztbxiY`aWQ6-dAYGCyvv}&00!bZ&FnlmfRf&(t12$ww`RKYFfI@Yyv(m5RqbCv^9LB zm-!A)jG~SssXH=%0Jzz_-Q2EF)JF#5qEgdwoAe zmd%nkM!Z%-vJ=*9X5pvhSWn3^00|GBCM(lq6p=xhsOhQt8<9YKyE<1o{?*<3+w$9x zHIC~zb(^;Bq;KNh98xll+j!j_v*#_-4vHFYInP}?5UmQoPZMQc@7r8o+H9x3nOlTS z?l@!l7vbb&J^9Ba`~RASnWqhTK02fFGrBWFa>h3A2!mpC=;WQ@@<$%k`NJuVa4WPU zBE9+OP1bGQfUbXu&agA5ySo`$LAb0M({TQjAIhiA4Dk+GAzU8l;Q7=$l^11RfZy*4 z&t@hG(@!5ubje&)n3M4GZ>B4s>{bWSufn0lmv{8<-9!IOJ{0ZkZT{&URaUb8N2xH8 z-8OZyy?l|&MV)6p({2`O?<6e`9t)sS4tpjTWm~oSQ#7Lr)Nc%bptYO34u?~<&i*&9 z-w#iDZLAj~`L^S%%&dE#XYY0aU!UL52KcRwGY)itOuFV81{~v85IiCx@r4TpX7NJd zo46gXv|TN%8>o`M9zWF=eU2f+)PR#)L59qVudX$DTzLSt3^(6HyH!NH*&Cf^CZ5g~R!s zLy?C$2#2RKa?Tm-h*!##Z=BG`!dbbG>jbj@C#HO#mmU(;h>7`)4i84wF?o|rw*<-f zkw4t`t}(6A(SvK*ELFv$9|m`a-zcttXpQXc-fNDNg9{tgO1w?Nt&8iR;Y zZdHZy0f^=fQka^LwCF@=SN4#0R7?6Ra+QP-EG_TGEt`9b?@*Ax$GxsQ{P2%g7kR-D z9S(XfXV%ksmlxWUxWY`w=Aej;t4<5WJSC>Eeuy?yd&_g!6)s-5ChpQdoAzN5m;=JT zDv-4>rIm=kgqC93St}AsJI8-4d14wu^zK0zK@Q#uc617Z+^&M>{EmDKH4lt5xdV?5 zWrZZ8WKyWZNa`txR+UbqwiF^nGi!3qM2)~SX7bA~BdX2pNd~Dv{@bLA0)8-M!sq`m zPW)BLhA!S(oB9GI@0XqJZ;i}fr$$E zR7RDWQj;-$0PGi?sZNAxYm3e!!L1mIWFC1!S-kyk%6(ZkOG%x~i|lsisflc^=cnoI zYXP7M!fL`F?To^07Xc!Ba$0vQjAl;2FSln*zgge zT}*iSpEM6Fdxe?}V%4~R+^Jlj+7-o`=X=m7pWh!#A$(|ek zhHEpPK7~^ojcqy~>5;7na@j&faR@($7TJnP1~5oM*bpfnf^f0$EyD!gdmhO67WNAT z(geE2^bYJ+9VG3hn!X&fFD*i+t-1iihx%=nVrErSY7huQZ6F^?*6gD2 z04Y44qpBg>g&&KIWz_0`THR?~ZH%gNCSH*#8p}WYJW#oHy`@ow3f*?e`O*&%spHS4Tn(8Cz6DkoN;tr1F$WHrqU^6l%i_OIl4j<$BqXl3^UR^ z&Phybff`vN#*r4rRyj|bwvG(7PO$#L5TWGR13V)dw`1&hTDxcLW8JddNJ^y@+)V_F z;uXY;=PUff@DeAeB)7jbczX9(Y>pmrrTB&`pwz*y5c3{c<5W;!mFg0$FlDXbMbsw)S!ki=FUL}K0;qTsVpaW}xm1-{feSi#kLOY)x*zP$rv z+Q@QI+p-@@L(bB@(YE!IK2v|G+{MaSxNA73tCka6d8HQC*7nreI*^yzOoN1!5{J5A*4Y z)$Vqc7X7REUu~!86L$$cinD8M=cWSJs^`C5-Bk&Fyysk_$ywsPQf-HyG{D50V_-j% ze>5DS(;-iwV$y0==S#45$=rZxT{4?fA}&943Oap?^j5sJoV!!2gL^`oF7rIyiJ>*R z3JQ-mviGdHc4@m#Qh!sGI=b&XFW1Tud!^d)*E=M{c?%i9G$Wg9 zqhtzD@<09as6ZU(7|zCQvA?YiXBcig5HpB%%Y0?qQ;_b0{f+VKtCLThZ_6@yzgXF6^ z*2Dnz#NqtSTv|GB=uH^^8K6o3!&5lFMl4AyK^DtY`bT%Jq|K2pk(AX3Nz%q~97EgS zz&;Aq9N1{L%@30wzx(4H(^G_>u(Vmjr*u~>_UC%m63DJZfB1_7*rHhqvYijs74nvV!1{5E z41NFajn2O?>|!OgiThH)D# zq-y85X>z5yk|H8_C!MJ!Mhcx}>zTk^BmwIz+w8#04zohq;bq0!9qZV4v;f} zEaNCDf0@$_eW&ROua;AEr}Zrz7JD+ic~@pJ4z0)X-(2^B2#MOfkTQ8P{34NJ_P;bg z5rd)8@f;}oZ7O-07E43$-&({@akM2EqAUk{ zkRtpf+%IX)JhFD`Z)R_xigR}ZpPmeW39meT zXn4Zc7ar@+@Uk(6XR8XnIMf!K7F&W~8VKLqlJ7%}ld3ipA0ZUmpI@EmI404kT0@mo zsNAkElMfUlbvWdYT%e(a_28&W&0#$`cU&k&Z5+|nByHNcBy8@}BxNdGzv)^oOPz#* zHu!%kITLWGx<8J~zH1`8EFs&7OpLW`m3@Eb_$VQGnSBS8B2sRmh4Li$r@6& z?AvRLhzS2tX_&m#|9U*n825a>cg~!9?)m-BIbYSlL1q%ovSf9&z(Katnq}uQ(+D?W zAdoRP1=-U})=#qQ#m^$&wnV;Nnw8cy5>?nOxp%$+l8BkPT^!-8u5MSR&86Xz-ly)( zW}e{Fz}kV~`*Sdbfq`zp!S;uzhKZ}St&6q2^C2&eeZ-QEXiW@qeRDAK;UoCB2pMw= zV^>=jW#stmAWqO#pp&H7g@xJ|4(Eh68Q9v{(hcip+88Ew2R~K~00Aj5C15SA4E=3E z?Ri@Zmrj`l67FL7LgpS$N~&@u2Mcesx_6X+`Ls>@LUf_xqbkr8CztdFFJX2Z!eWm6 zL97aJqpi_7Pj@Bo?gLUmd?LnJt!Z-jD4xDlLF^hEJR>lymLQV=KC;A?ZpEse9+1L{ z<;C?QV|qcR6rt`Po#IuO6~rfkJfM$u%i(o=PB;L7F=U>`m7OkvgG2WKZ%bj1d&8os{xRqm5{#dr}-&IZDJ9`b6 zjD{`Q;Uq1D?K(v&pM^$hlBzcrYWKEHsa}B2WP<~X{qKdHNP1u*;-4pG7&m_Uv_KhC zV=k9LLtfasn>X&@-T- zW6>qQa#7cXXE?iK=5YmoPzdvyj=?OhG*`Lah57yp1ie0W$v-!jh!k4orJh@x5h;W} z9J)gS_z_Bt_OSk76R2KcxRt_;M`40+M_&zd=}CHXV)}N90h|60Itn z7hQ;#sCNYQJL9sGy>-LQ%n>HidK<^7GCV(J9YP(LnPy>UMJXL!zwW*$(DJd(*n?Q@ zp0d*QzRGWYay_rVRq;WZDZ1Fm+zDKcs`Q!9=g|h9;h7AlDr*+&x3Sjnrn0uEq zFv-?rnB%Rh(tDiz`rf(9H2_^ocR$cKb$W-FLPmd{y3{TB>SuV>M~f_8K^mzRJ>`zB z`&-uL4zx5)BK{ssjUf^^QH(`$oQ>Yk>@6JB#Dddqq$z(bIKyW?5UB&bayww$pl2aE zv(&=iNqn4dXp5zyvuI|xxQ91jMAhdSK#jMwrmJYjJ*k<6PG^h2Yw|n>`vbZbfedK3 z95)ucSMa^V8Od1g%ykjzHH_rYX6ozA@=T9z0>pNSf&>a8!#^fJt@b5Q^I7M?yGbgi zvuoCJC6!5P=JIP{P^F88wBt@NKY^8l2c)EQZ~3}P=vfW91_g-LUF-9v^d1e8iYX)RYo zRwXhg0rRkD!+xhvAowLW7TFo(;Qk+-K5|>}z6+D1v5VD@PG9p!hak|d*fa+Osb(pG$=7EPhcCDS258H9l^fr~kF9Z)*wTe{q-&)nU0 zFbhN`ogfkpy6?RjeJ-vVSo)cZBZ&MK7u$J=&iMMZmJRWd%K$bkhw+5lRhi=ze&-A7 z9W#X9rd*%~!^jytV58+eU~a5%4U&da5$m#6qZuF}uXd7{f}HUnzr?aez8Xs>yPY%n zgjj~~wDA(Zi?{7Y>4x|}0+(_SBzfrrD;6Rt`)P8(TX!7AE@DJ-jZxL2~?Wp&OgaUp0tnMyVGg81)Y>+wKxV=9V1 zWDLcwEjl_fY}9Np40mo6UWE=ee*l={%7WJRY}B$zV%Ggf@XbO6Z17?YZggG4anh}% z9rn%?-za&d@cQ45R@cH)X03}_@WHJelhra#2c^>dr^7DU*bVhWmflr^`Mk__y&!LT z$w%@^&q%00-1%zlL}V~b;gvp|J~QZ&n0o(>aMJLVuQRHW4|)`pS#MKu(O~3?s_q3? zh)a&sG(~Tb8svWUe`)$sPCZG9_VqILlb0z*ka|;q7;Sy}lwgyBXC^fCHmo-~_IjL5 zu)VBpmMC-eUF_~xE*{H~w(%XYwsiNk>^Jbt((%KJ>@wsFoaN*B@M;Lx(s01gU9euB%sOi-6X%MXQx^!iW6edo~@-^Q_OUXw{Brj`@%p#vlO4w(_3l}o=zDVGYRoIAjz0Cr&E_`&$dMhzU!)ZdJ@tR=8$qSspc?ub`_^kj zfsrn`I68SFX{mCXAuK-rn_YO#G&;$1#AG!nod}a73OudXK0*6z<|fuB z&!Lx3&Hh0kLI!b{s1Y>mLYdKC;l@L5Zq!b15px2LY-U~WBU}Zu{(NN$q|R2 zy%^0rvbxTwH0XB4hIQCON|AS`3}$WeSlI-KmCr7M%}LB^<>JK>;*F_|`{FGhezqeG z*LY0Ol=ZcY&u8J%t6-taJ`bltMVtj&jTXY~#h=DZuamUr%HQn{ePx(@F0`MyofWEl z3dbzn_K~@;XnYpqlRJ|wer!cDHc@HT12l`|OO}WT&KDVzif(#M*S%~jmd@StuG=Iq zqs$~$Z($k|mx8I1XK`@T^bkK+&Zb`!gtObUdQ%g7EAsbhZ}HK5NH3FdplkrFGWzU* zwO%+JZD#U0ZUk7!AmSvOx2ge_elE_Zw`pYMqYW<`NAULPjZ=}iTl5b;B z^U_ys&KPyyEyd}p$XG~lBdUp`QWV?7kccrROo>f4t6gYwI43Z&(K$nPhdas3Ds{20 z`B|{|Lgj4P?5Tuz^4y|Ky?6PT!O{Xz0dbUEmE`i|X`^no7AuOAS_Jy>mX#;V?{PB$ zU2ppefCgR*4U&;FDwXk)-liXaCEMA|uZ;h|cZV^St4N+|X!cElwv;8;G)qT-@Yvoah?*_De1;Lpu07vyKb^zjM+xl69p>;uci z32?#H*PyBwLC_h>4+9=}!3ZB--hfM|yk^~%GS)tF&=8x+WV?aOVy(`_y$QTWUsFK% z+;l=*;`*kQDbb*y8^WgU`50Uoyh#^QBm=$I&7V#%U5=ki_Ex2{!@Tok$zCqtjBGsL z)8b`;?5@4~QIb-o#QTA{;X-v)-Z;~ASdSfzx8LyCE>we$-r&QU` z8|L5zucMQLqdC%=)7%-_B^lPhM~u_utqdnZ?)oyBz3g5@;F2$rAY;^87oD~C89Gr+ ztRKSz-Rrp;y>iD-EkZ(;ik~jsYU??jg_A#h6U&kgm^!@T(I;&Z_d-sg$gK&XdHRpY z^;ef=>Y^y(JPT^x(OYXnA8qs{VdivLX_zv4*|L0Ovpj`WovVhuSFf3yIsAMl+B>1I zU!{>E$mRZXYk}05Jr0LYZ`>Z`8|oXjwAKK%Pxq2(nU0W_Qctno(&Yv2s?@mlY7P)0 za4ySNsk;qh9j%>ca_eV$$lB3C{{AT^@grshBKJ9dYx$_U(QxAdwsb1-v?waKwLF1b zQ)yQK%Jax6sa?x~IJR-CUE^wRlT+hR=6%h>@n%Auw1q>{Q9((ak57y5Lg57j;=)BW zM-oysz6*SOQ(Ou_u8y|OqKjPu?*t|>eEljET7&((l<(%Nbd$8VyN&ylPKYwme`5@T?h(f2;Wpuqaz=7N4QIrBHQdeOoz$Ihac` z(NqQ0tbdNeVAQa8y2yr>)RCHQ6{Z@|(o9>}Mg6bjkX>h%* zvwIk1Q#^EXx=o62Bm~1JHmE!L=uMwxOxp-uOEehY%VF{N3^EwJJ_SfGv)2pmfXs1U z_Kgl9V^d+d6iiZxTq{6v4nMaK@BJ`Es6R+j{SnheNiV|w?vd0g41rMk5=uMs8`1bh zeb$OOJW;D0Jl8y>uEZA_z{NUWZz5B9Con0nkbX|c<2VoEZ~wqJiLofT|LTw<@jX%;mm$Fp2>B55hrm3Pn2JO!$D6;b;E`(xKcIIuzX#76tu^44aSpfCrcN4SHms zKRO%TFcHNTMOsh)j*VuYhz>?~4n%>&k*(}^;9q; zPxNE`CJqZ6=P7^^NJZX}zrXzN0pfo;44_M)ZzxAekuv_B)b}s}or}J;0>#zi`7`&> zMhkQ>`m!k$xF0!O`%~R~1EUsEp~KOaz@XqaME?Lkx*+B-c)!V@FCsvJ{Um-5{@s!S zbQSbzUX+R~@=5i(x;dos%cL(#<@l+s?<)I`m{OVFs~ilIk>j3&rxyOV*)sI0F4To@ z{VnpBi7#{w^l289#`u-LyzC>BF6eyp%q@z)EdSShv^*}l271y6rSV?*uQh&2A)%|F z=L}FPm(>1V39aw3%I`|-$1~rL{kzlXM~R=&&A~nRtJHpcgDMz$wBSLs^WVky v;~iA-vg3+>kA4mi$HzYhkPN^1|3Vx)(7-{?onT;`MgCMHYry~d{$KwCgG0b` literal 0 HcmV?d00001 diff --git a/lib/runtime/jar/nailgun-0.7.1.jar b/lib/runtime/jar/nailgun-0.7.1.jar new file mode 100644 index 0000000000000000000000000000000000000000..05cbbaf44f160c8aa09aec95da105e10a120601f GIT binary patch literal 25685 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 literal 0 HcmV?d00001 diff --git a/project.properties b/project.properties index 844e923..a3c9152 100644 --- a/project.properties +++ b/project.properties @@ -1,7 +1,7 @@ -#Sat, 06 Nov 2010 10:35:28 -0500 +#Sat, 06 Nov 2010 16:20:53 -0500 lib.local=true name=groovy-twitter-cli version=0.1 -build.number=19 +build.number=60 nailgun.classpath.dir=/home/jdbernard/programs/nailgun/classpath win32.nailgun.classpath.dir=C\:/Documents and Settings/jbernard/My Documents/ng-classpath diff --git a/src/com/jdbernard/twitter/ConsoleColor.java b/src/com/jdbernard/twitter/ConsoleColor.java new file mode 100644 index 0000000..26c033c --- /dev/null +++ b/src/com/jdbernard/twitter/ConsoleColor.java @@ -0,0 +1,58 @@ +package com.jdbernard.twitter; + +public class ConsoleColor { + + public final Colors fg; + public final Colors bg; + public final boolean bright; + + public static enum Colors { + BLACK, RED, GREEN, YELLOW, BLUE, MAGENTA, CYAN, WHITE } + + public ConsoleColor(String propString) { + String[] vals = propString.split("[,;: ]"); + + fg = Colors.valueOf(vals[0]); + + if (vals.length == 2) { + bg = null; + bright = Boolean.parseBoolean(vals[1]); + } else if (vals.length == 3) { + bg = Colors.valueOf(vals[1]); + bright = Boolean.parseBoolean(vals[2]); + } else { bg = null; bright = false; } + } + + public ConsoleColor(Colors fgColor) { this(fgColor, Colors.BLACK, false); } + + public ConsoleColor(Colors fgColor, boolean bright) { + this(fgColor, Colors.BLACK, bright); + } + + public ConsoleColor(Colors fgColor, Colors bgColor, boolean bright) { + this.fg = fgColor; this.bg = bgColor; this.bright = bright; + } + + public String toString() { + String result = "\u001b["; + boolean needSemi = false; + + if (bright) { + result += "1"; + needSemi = true; + } + + if (fg != null) { + if (needSemi) result += ";"; + result += "3" + Integer.toString(fg.ordinal()); + needSemi = true; + } + + if (bg != null) { + if (needSemi) result += ";"; + result += "4" + Integer.toString(bg.ordinal()); + } + + return result + "m"; + } +} diff --git a/src/com/jdbernard/twitter/TwitterCLI.groovy b/src/com/jdbernard/twitter/TwitterCLI.groovy index fe9afe3..0c1b43a 100644 --- a/src/com/jdbernard/twitter/TwitterCLI.groovy +++ b/src/com/jdbernard/twitter/TwitterCLI.groovy @@ -1,5 +1,6 @@ package com.jdbernard.twitter +import com.martiansoftware.nailgun.NGContext import twitter4j.Twitter import twitter4j.TwitterFactory import twitter4j.conf.Configuration @@ -7,102 +8,235 @@ import twitter4j.conf.PropertyConfiguration public class TwitterCLI { + private static String EOL = System.getProperty("line.separator") + private static TwitterCLI nailgunInst private Twitter twitter + private Scanner stdin + + private Map colors = [:] + + private int terminalWidth + private boolean colored + public static void main(String[] args) { TwitterCLI inst = new TwitterCLI(new File(System.getProperty("user.home"), ".groovy-twitter-cli-rc")) - inst.run(args as List) + inst.run((args as List) as Queue) } - public static void nailMain(String[] args) { + public static void nailMain(NGContext context) { + if (nailgunInst == null) + nailgunInst = new TwitterCLI(new File( + System.getProperty("user.home"), ".groovy-twitter-cli-rc")) + else + nailgunInst.stdin = new Scanner(context.in) - if (nailgunInst == null) nailgunInst = new TwitterCLI(new File( - System.getProperty("user.home"), ".groovy-twitter-cli-rc")) - - nailgunInst.run(args as List) + nailgunInst. + nailgunInst.run((context.args as List) as Queue) } - public static void setColor(boolean bright, int code) { - print "\u001b[${bright?'1':'0'};${code}m" + public static void reconfigure(Queue args) { + if (nailgunInst == null) main(args as String[]) + else { + nailgunInst = null + nailgunInst = new TwitterCLI(new File( + System.getProperty("user.home"), ".groovy-twitter-cli-rc")) + + nailgunInst.run(args) + } } - public static void resetColor() { print "\u001b[m" } + static String wrapToWidth(String text, int width, String prefix, String suffix) { + int lastSpaceIdx = 0; + int curLineLength = 0; + int lineStartIdx = 0; + int i = 0; + int actualWidth = width - prefix.length() - suffix.length() + String wrapped = "" - public static void colorPrint(def message, boolean bright, int color) { - setColor(bright, color) - print message - resetColor() + text = text.replaceAll("[\n\r]", " ") + + for (i = 0; i < text.length(); i++) { + + curLineLength++ + if (curLineLength > actualWidth) { + wrapped += prefix + text[lineStartIdx.. 1) + wrapped += prefix + text[lineStartIdx.. conf = new PropertyConfiguration(is) } + Properties cfg = new Properties() + propFile.withInputStream { is -> cfg.load(is) } // create a twitter instance - twitter = (new TwitterFactory(conf)).getInstance() + twitter = (new TwitterFactory(new PropertyConfiguration(cfg))).getInstance() + // configure the colors + colors.author = new ConsoleColor(cfg.getProperty("colors.author", "BLUE:false")) + colors.mentioned = new ConsoleColor(cfg.getProperty("colors.mentioned", "GREEN:false")) + colors.error = new ConsoleColor(cfg.getProperty("colors.error", "RED:true")) + colors.option = new ConsoleColor(cfg.getProperty("colors.option", "YELLOW:true")) + colors.even = new ConsoleColor(cfg.getProperty("colors.even", "WHITE")) + colors.odd = new ConsoleColor(cfg.getProperty("colors.odd", "YELLOW")) + + // configure the terminal width + terminalWidth = (System.getenv().COLUMNS ?: cfg.terminalWidth ?: 79) as int + + colored = (cfg.colored ?: 'true') as boolean + + stdin = new Scanner(System.in) } - public void run(List args) { + public void run(Queue args) { if (args.size() < 1) printUsage() - switch (args[0].toLowerCase()) { - case ~/t.*/: timeline(args.tail()); break - case ~/p.*/: post(args.tail()); break + while (args.peek()) { + def command = args.poll() - default: - printUsage() - } + switch (command.toLowerCase()) { + case ~/h.*/: help(args); break + case ~/p.*/: post(args); break + case ~/r.*/: reconfigure(args); break + case ~/se.*/: set(args); break + case ~/sh.*/: show(args); break + case ~/t.*/: timeline(args); break - } - - public void timeline(List args) { - - // default to showing my friends timeline - if (args.size() == 0) args = ["friends"] - - while (args.size() > 0) { - def option = args.pop() - switch (option) { - // friends - case ~/f.*/: printTimeline(twitter.friendsTimeline); break - // mine - case ~/m.*/: printTimeline(twitter.userTimeline); break - // user - case ~/u.*/: - if (args.size() == 0) - colorPrintln("No user specificied.", true, 31) - else printTimeline(twitter.getUserTimeline(args.pop())) - break; default: - colorPrint("Unknown timeline: ", true, 31) - colorPrintln(option, true, 33) - break; + printUsage() } } } + public void help(Queue args) { + + } + + public void post(Queue args) { + def status = args.poll() + + if (!status) { + println color("post ", colors.option) + + color("command requires one option: ", colors.error) + + "twitter post " + return + } + + if (status.length() > 140) { + println color("Status exceeds Twitter's 140 character limit.", colors.error) + return + } + + print "Update status: '$status'? " + if (stdin.nextLine() ==~ /yes|y|true|t/) + twitter.updateStatus(status) + } + + public void set(Queue args) { + def option = args.poll() + def value = args.poll() + + if (!value) { // note: if option is null, value is null + println color("set", colors.option) + + color(" command requires two options: ", colors.error) + + "twitter set " + return + } + + switch (option) { + case "terminalWidth": terminalWidth = value as int; break + case "colored": colored = value.toLowerCase() ==~ /true|t|on|yes|y/ + break + + default: + println color("No property named ", colors.error) + + color(option, colors.option) + + color(" exists.", colors.error) + } + } + + public void show(Queue args) { + + } + + public void timeline(Queue args) { + + String timeline = args.poll() ?: "friends" + + switch (timeline) { + // friends + case ~/f.*/: printTimeline(twitter.friendsTimeline); break + // mine + case ~/m.*/: printTimeline(twitter.userTimeline); break + // user + case ~/u.*/: + String user = args.poll() + if (user) { + if (user.isNumber()) + printTimeline(twitter.getUserTimeline(user as int)) + else printTimeline(twitter.getUserTimeline(user)) + } else println color("No user specified.", colors.error) + break; + default: + println color("Unknown timeline: ", colors.error) + + color(timeline, colors.option) + break; + } + } + void printTimeline(def timeline) { + + int authorLen = 0, textLen + String statusIndent + timeline.each { status -> - colorPrint(status.user.screenName, true, 34) + if (status.user.screenName.length() > authorLen) + authorLen = status.user.screenName.length() + } + + timeline.eachWithIndex { status, rowNum -> + String text = status.text + print color(status.user.screenName.padLeft(authorLen), colors.author) print ": " - println status.text - println "" + statusIndent = "".padLeft(authorLen + 2) + textLen = terminalWidth - statusIndent.length() + + if (text.length() > textLen) { + text = wrapToWidth(text, terminalWidth, statusIndent, ""). + substring(statusIndent.length()) + } + + text = text.replaceAll(/(@\w+)/, color("\$1", colors.mentioned)) + println color(text, (rowNum % 2 == 0 ? colors.even : colors.odd)) } } public static void printUsage() { // TODO } + + public String resetColor() { colored ? "\u001b[m" : "" } + + public String color(def message, ConsoleColor color) { + if (!colored) return message + return color.toString() + message + resetColor() + } + }