time.js 14 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052
  1. #!/usr/bin/env node
  2. /**
  3. * A clock using blessed
  4. * Copyright (c) 2013, Christopher Jeffrey (MIT License).
  5. * https://github.com/chjj/blessed
  6. */
  7. process.title = 'time.js';
  8. var argv = process.argv;
  9. if (~argv.indexOf('-h') || ~argv.indexOf('--help')) {
  10. console.log('Options:');
  11. console.log('-s - Show seconds.');
  12. console.log('-n - No leading zero on hours.');
  13. console.log('-d - Show date box.');
  14. console.log('--skinny - Skinny text.');
  15. return process.exit(0);
  16. }
  17. var blessed = require('blessed');
  18. var screen = blessed.screen({
  19. autoPadding: true
  20. });
  21. var lastTime;
  22. var positions = {};
  23. var container = blessed.box({
  24. parent: screen,
  25. top: 'center',
  26. left: 'center',
  27. width: 'shrink',
  28. height: 9,
  29. //padding: 2,
  30. //border: {
  31. // type: 'line',
  32. // fg: 'black'
  33. //}
  34. });
  35. // Workaround for centering shrunken box.
  36. container.on('prerender', function() {
  37. var lpos = container._getCoords(true);
  38. if (lpos) {
  39. container.rleft = (screen.width - (lpos.xl - lpos.xi)) / 2 | 0;
  40. }
  41. });
  42. var date = blessed.box({
  43. parent: screen,
  44. top: 1,
  45. left: 1,
  46. //top: '80%',
  47. //left: 'center',
  48. width: 'shrink',
  49. height: 'shrink',
  50. border: {
  51. type: 'line',
  52. fg: 'black'
  53. }
  54. });
  55. date.hide();
  56. var wid = ~argv.indexOf('--skinny') ? 1 : 2;
  57. // var bch = ' ';
  58. var bch = '│';
  59. var inverse = true;
  60. // var bch = '*';
  61. // var bch = '·';
  62. // var bch = '│';
  63. // var bch = '◆';
  64. // var bch = '▪';
  65. // var inverse = false;
  66. // TODO: Potentially make height of each char 9 instead
  67. // of 8 so we can vertically center horizontal lines
  68. // in 4, 8, etc.
  69. for (var i = 0; i < 10; i++) {
  70. var symbols = positions[i] = {};
  71. /**
  72. * Zero
  73. */
  74. symbols[0] = blessed.box({
  75. parent: container,
  76. top: 0,
  77. left: 0,
  78. width: 10,
  79. height: 9
  80. });
  81. blessed.box({
  82. parent: symbols[0],
  83. top: 0,
  84. left: 0,
  85. right: 0,
  86. height: 1,
  87. ch: bch,
  88. style: {
  89. fg: 'default',
  90. inverse: inverse
  91. }
  92. });
  93. blessed.box({
  94. parent: symbols[0],
  95. top: 0,
  96. left: 0,
  97. bottom: 0,
  98. width: wid,
  99. ch: bch,
  100. style: {
  101. fg: 'default',
  102. inverse: inverse
  103. }
  104. });
  105. blessed.box({
  106. parent: symbols[0],
  107. top: 0,
  108. right: 0,
  109. bottom: 0,
  110. width: wid,
  111. ch: bch,
  112. style: {
  113. fg: 'default',
  114. inverse: inverse
  115. }
  116. });
  117. blessed.box({
  118. parent: symbols[0],
  119. top: 8,
  120. left: 0,
  121. right: 0,
  122. height: 1,
  123. ch: bch,
  124. style: {
  125. fg: 'default',
  126. inverse: inverse
  127. }
  128. });
  129. symbols[0].hide();
  130. /**
  131. * One
  132. */
  133. symbols[1] = blessed.box({
  134. parent: container,
  135. top: 0,
  136. width: 10,
  137. height: 9
  138. });
  139. blessed.box({
  140. parent: symbols[1],
  141. top: 0,
  142. left: 'center',
  143. width: 2,
  144. ch: bch,
  145. style: {
  146. fg: 'default',
  147. inverse: inverse
  148. }
  149. });
  150. symbols[1].hide();
  151. /**
  152. * Two
  153. */
  154. symbols[2] = blessed.box({
  155. parent: container,
  156. top: 0,
  157. left: 0,
  158. width: 10,
  159. height: 9
  160. });
  161. blessed.box({
  162. parent: symbols[2],
  163. top: 0,
  164. left: 0,
  165. right: 0,
  166. height: 1,
  167. ch: bch,
  168. style: {
  169. fg: 'default',
  170. inverse: inverse
  171. }
  172. });
  173. blessed.box({
  174. parent: symbols[2],
  175. top: 0,
  176. right: 0,
  177. height: 4,
  178. width: wid,
  179. ch: bch,
  180. style: {
  181. fg: 'default',
  182. inverse: inverse
  183. }
  184. });
  185. blessed.box({
  186. parent: symbols[2],
  187. top: 4,
  188. left: 0,
  189. right: 0,
  190. height: 1,
  191. ch: bch,
  192. style: {
  193. fg: 'default',
  194. inverse: inverse
  195. }
  196. });
  197. blessed.box({
  198. parent: symbols[2],
  199. top: 4,
  200. left: 0,
  201. height: 4,
  202. width: wid,
  203. ch: bch,
  204. style: {
  205. fg: 'default',
  206. inverse: inverse
  207. }
  208. });
  209. blessed.box({
  210. parent: symbols[2],
  211. top: 8,
  212. left: 0,
  213. right: 0,
  214. height: 1,
  215. ch: bch,
  216. style: {
  217. fg: 'default',
  218. inverse: inverse
  219. }
  220. });
  221. symbols[2].hide();
  222. /**
  223. * Three
  224. */
  225. symbols[3] = blessed.box({
  226. parent: container,
  227. top: 0,
  228. left: 0,
  229. width: 10,
  230. height: 9
  231. });
  232. blessed.box({
  233. parent: symbols[3],
  234. top: 0,
  235. bottom: 0,
  236. right: 0,
  237. width: wid,
  238. height: 9,
  239. ch: bch,
  240. style: {
  241. fg: 'default',
  242. inverse: inverse
  243. }
  244. });
  245. blessed.box({
  246. parent: symbols[3],
  247. top: 0,
  248. right: 0,
  249. left: 0,
  250. height: 1,
  251. ch: bch,
  252. style: {
  253. fg: 'default',
  254. inverse: inverse
  255. }
  256. });
  257. blessed.box({
  258. parent: symbols[3],
  259. top: 4,
  260. right: 0,
  261. left: 0,
  262. height: 1,
  263. ch: bch,
  264. style: {
  265. fg: 'default',
  266. inverse: inverse
  267. }
  268. });
  269. blessed.box({
  270. parent: symbols[3],
  271. top: 8,
  272. right: 0,
  273. left: 0,
  274. height: 1,
  275. ch: bch,
  276. style: {
  277. fg: 'default',
  278. inverse: inverse
  279. }
  280. });
  281. symbols[3].hide();
  282. /**
  283. * Four
  284. */
  285. symbols[4] = blessed.box({
  286. parent: container,
  287. top: 0,
  288. left: 0,
  289. width: 10,
  290. height: 9
  291. });
  292. blessed.box({
  293. parent: symbols[4],
  294. top: 0,
  295. bottom: 0,
  296. right: 0,
  297. width: wid,
  298. height: 9,
  299. ch: bch,
  300. style: {
  301. fg: 'default',
  302. inverse: inverse
  303. }
  304. });
  305. blessed.box({
  306. parent: symbols[4],
  307. top: 4,
  308. right: 0,
  309. left: 0,
  310. height: 1,
  311. ch: bch,
  312. style: {
  313. fg: 'default',
  314. inverse: inverse
  315. }
  316. });
  317. blessed.box({
  318. parent: symbols[4],
  319. top: 0,
  320. left: 0,
  321. width: wid,
  322. height: 4,
  323. ch: bch,
  324. style: {
  325. fg: 'default',
  326. inverse: inverse
  327. }
  328. });
  329. symbols[4].hide();
  330. /**
  331. * Five
  332. */
  333. symbols[5] = blessed.box({
  334. parent: container,
  335. top: 0,
  336. left: 0,
  337. width: 10,
  338. height: 9
  339. });
  340. blessed.box({
  341. parent: symbols[5],
  342. top: 0,
  343. left: 0,
  344. right: 0,
  345. height: 1,
  346. ch: bch,
  347. style: {
  348. fg: 'default',
  349. inverse: inverse
  350. }
  351. });
  352. blessed.box({
  353. parent: symbols[5],
  354. top: 0,
  355. left: 0,
  356. height: 4,
  357. width: wid,
  358. ch: bch,
  359. style: {
  360. fg: 'default',
  361. inverse: inverse
  362. }
  363. });
  364. blessed.box({
  365. parent: symbols[5],
  366. top: 4,
  367. left: 0,
  368. right: 0,
  369. height: 1,
  370. ch: bch,
  371. style: {
  372. fg: 'default',
  373. inverse: inverse
  374. }
  375. });
  376. blessed.box({
  377. parent: symbols[5],
  378. top: 4,
  379. right: 0,
  380. height: 4,
  381. width: wid,
  382. ch: bch,
  383. style: {
  384. fg: 'default',
  385. inverse: inverse
  386. }
  387. });
  388. blessed.box({
  389. parent: symbols[5],
  390. top: 8,
  391. left: 0,
  392. right: 0,
  393. height: 1,
  394. ch: bch,
  395. style: {
  396. fg: 'default',
  397. inverse: inverse
  398. }
  399. });
  400. symbols[5].hide();
  401. /**
  402. * Six
  403. */
  404. symbols[6] = blessed.box({
  405. parent: container,
  406. top: 0,
  407. left: 0,
  408. width: 10,
  409. height: 9
  410. });
  411. blessed.box({
  412. parent: symbols[6],
  413. top: 0,
  414. left: 0,
  415. right: 0,
  416. height: 1,
  417. ch: bch,
  418. style: {
  419. fg: 'default',
  420. inverse: inverse
  421. }
  422. });
  423. blessed.box({
  424. parent: symbols[6],
  425. top: 0,
  426. left: 0,
  427. bottom: 0,
  428. width: wid,
  429. ch: bch,
  430. style: {
  431. fg: 'default',
  432. inverse: inverse
  433. }
  434. });
  435. blessed.box({
  436. parent: symbols[6],
  437. top: 4,
  438. left: 0,
  439. right: 0,
  440. height: 1,
  441. ch: bch,
  442. style: {
  443. fg: 'default',
  444. inverse: inverse
  445. }
  446. });
  447. blessed.box({
  448. parent: symbols[6],
  449. top: 4,
  450. right: 0,
  451. height: 4,
  452. width: wid,
  453. ch: bch,
  454. style: {
  455. fg: 'default',
  456. inverse: inverse
  457. }
  458. });
  459. blessed.box({
  460. parent: symbols[6],
  461. top: 8,
  462. left: 0,
  463. right: 0,
  464. height: 1,
  465. ch: bch,
  466. style: {
  467. fg: 'default',
  468. inverse: inverse
  469. }
  470. });
  471. symbols[6].hide();
  472. /**
  473. * Seven
  474. */
  475. symbols[7] = blessed.box({
  476. parent: container,
  477. top: 0,
  478. left: 0,
  479. width: 10,
  480. height: 9
  481. });
  482. blessed.box({
  483. parent: symbols[7],
  484. top: 0,
  485. bottom: 0,
  486. right: 0,
  487. width: wid,
  488. height: 9,
  489. ch: bch,
  490. style: {
  491. fg: 'default',
  492. inverse: inverse
  493. }
  494. });
  495. blessed.box({
  496. parent: symbols[7],
  497. top: 0,
  498. right: 0,
  499. left: 0,
  500. height: 1,
  501. ch: bch,
  502. style: {
  503. fg: 'default',
  504. inverse: inverse
  505. }
  506. });
  507. symbols[7].hide();
  508. /**
  509. * Eight
  510. */
  511. symbols[8] = blessed.box({
  512. parent: container,
  513. top: 0,
  514. left: 0,
  515. width: 10,
  516. height: 9
  517. });
  518. blessed.box({
  519. parent: symbols[8],
  520. top: 0,
  521. left: 0,
  522. right: 0,
  523. height: 1,
  524. ch: bch,
  525. style: {
  526. fg: 'default',
  527. inverse: inverse
  528. }
  529. });
  530. blessed.box({
  531. parent: symbols[8],
  532. top: 0,
  533. left: 0,
  534. bottom: 0,
  535. width: wid,
  536. ch: bch,
  537. style: {
  538. fg: 'default',
  539. inverse: inverse
  540. }
  541. });
  542. blessed.box({
  543. parent: symbols[8],
  544. top: 4,
  545. left: 0,
  546. right: 0,
  547. height: 1,
  548. ch: bch,
  549. style: {
  550. fg: 'default',
  551. inverse: inverse
  552. }
  553. });
  554. blessed.box({
  555. parent: symbols[8],
  556. top: 0,
  557. right: 0,
  558. bottom: 0,
  559. width: wid,
  560. ch: bch,
  561. style: {
  562. fg: 'default',
  563. inverse: inverse
  564. }
  565. });
  566. blessed.box({
  567. parent: symbols[8],
  568. top: 8,
  569. left: 0,
  570. right: 0,
  571. height: 1,
  572. ch: bch,
  573. style: {
  574. fg: 'default',
  575. inverse: inverse
  576. }
  577. });
  578. symbols[8].hide();
  579. /**
  580. * Nine
  581. */
  582. symbols[9] = blessed.box({
  583. parent: container,
  584. top: 0,
  585. left: 0,
  586. width: 10,
  587. height: 9
  588. });
  589. blessed.box({
  590. parent: symbols[9],
  591. top: 0,
  592. left: 0,
  593. right: 0,
  594. height: 1,
  595. ch: bch,
  596. style: {
  597. fg: 'default',
  598. inverse: inverse
  599. }
  600. });
  601. blessed.box({
  602. parent: symbols[9],
  603. top: 0,
  604. left: 0,
  605. height: 4,
  606. width: wid,
  607. ch: bch,
  608. style: {
  609. fg: 'default',
  610. inverse: inverse
  611. }
  612. });
  613. blessed.box({
  614. parent: symbols[9],
  615. top: 4,
  616. left: 0,
  617. right: 0,
  618. height: 1,
  619. ch: bch,
  620. style: {
  621. fg: 'default',
  622. inverse: inverse
  623. }
  624. });
  625. blessed.box({
  626. parent: symbols[9],
  627. top: 0,
  628. right: 0,
  629. bottom: 0,
  630. width: wid,
  631. ch: bch,
  632. style: {
  633. fg: 'default',
  634. inverse: inverse
  635. }
  636. });
  637. blessed.box({
  638. parent: symbols[9],
  639. top: 8,
  640. left: 0,
  641. right: 0,
  642. height: 1,
  643. ch: bch,
  644. style: {
  645. fg: 'default',
  646. inverse: inverse
  647. }
  648. });
  649. symbols[9].hide();
  650. /**
  651. * Colon
  652. */
  653. symbols[':'] = blessed.box({
  654. parent: container,
  655. top: 0,
  656. left: 0,
  657. width: 5,
  658. height: 9
  659. });
  660. blessed.box({
  661. parent: symbols[':'],
  662. top: 3,
  663. left: 'center',
  664. width: 2,
  665. height: 1,
  666. ch: bch,
  667. style: {
  668. fg: 'black',
  669. inverse: inverse
  670. }
  671. });
  672. blessed.box({
  673. parent: symbols[':'],
  674. top: 6,
  675. left: 'center',
  676. width: 2,
  677. height: 1,
  678. ch: bch,
  679. style: {
  680. fg: 'black',
  681. inverse: inverse
  682. }
  683. });
  684. symbols[':'].hide();
  685. /**
  686. * A
  687. */
  688. symbols['a'] = blessed.box({
  689. parent: container,
  690. top: 2,
  691. left: 0,
  692. width: 10,
  693. height: 7
  694. });
  695. blessed.box({
  696. parent: symbols['a'],
  697. top: 0,
  698. left: 0,
  699. right: 0,
  700. height: 1,
  701. ch: bch,
  702. style: {
  703. fg: 'blue',
  704. inverse: inverse
  705. }
  706. });
  707. blessed.box({
  708. parent: symbols['a'],
  709. top: 0,
  710. left: 0,
  711. bottom: 0,
  712. width: wid,
  713. ch: bch,
  714. style: {
  715. fg: 'blue',
  716. inverse: inverse
  717. }
  718. });
  719. blessed.box({
  720. parent: symbols['a'],
  721. top: 3,
  722. left: 0,
  723. right: 0,
  724. height: 1,
  725. ch: bch,
  726. style: {
  727. fg: 'blue',
  728. inverse: inverse
  729. }
  730. });
  731. blessed.box({
  732. parent: symbols['a'],
  733. top: 0,
  734. right: 0,
  735. bottom: 0,
  736. width: wid,
  737. ch: bch,
  738. style: {
  739. fg: 'blue',
  740. inverse: inverse
  741. }
  742. });
  743. symbols['a'].hide();
  744. /**
  745. * P
  746. */
  747. symbols['p'] = blessed.box({
  748. parent: container,
  749. top: 2,
  750. left: 0,
  751. width: 10,
  752. height: 7
  753. });
  754. blessed.box({
  755. parent: symbols['p'],
  756. top: 0,
  757. left: 0,
  758. right: 0,
  759. height: 1,
  760. ch: bch,
  761. style: {
  762. fg: 'blue',
  763. inverse: inverse
  764. }
  765. });
  766. blessed.box({
  767. parent: symbols['p'],
  768. top: 0,
  769. right: 0,
  770. height: 4,
  771. width: wid,
  772. ch: bch,
  773. style: {
  774. fg: 'blue',
  775. inverse: inverse
  776. }
  777. });
  778. blessed.box({
  779. parent: symbols['p'],
  780. top: 0,
  781. left: 0,
  782. bottom: 0,
  783. width: wid,
  784. ch: bch,
  785. style: {
  786. fg: 'blue',
  787. inverse: inverse
  788. }
  789. });
  790. blessed.box({
  791. parent: symbols['p'],
  792. top: 3,
  793. left: 0,
  794. right: 0,
  795. height: 1,
  796. ch: bch,
  797. style: {
  798. fg: 'blue',
  799. inverse: inverse
  800. }
  801. });
  802. symbols['p'].hide();
  803. /**
  804. * M
  805. */
  806. symbols['m'] = blessed.box({
  807. parent: container,
  808. top: 2,
  809. left: 0,
  810. width: 10,
  811. height: 7
  812. });
  813. blessed.box({
  814. parent: symbols['m'],
  815. top: 0,
  816. left: 0,
  817. right: 0,
  818. height: 1,
  819. ch: bch,
  820. style: {
  821. fg: 'black',
  822. inverse: inverse
  823. }
  824. });
  825. blessed.box({
  826. parent: symbols['m'],
  827. top: 0,
  828. left: 0,
  829. bottom: 0,
  830. width: wid,
  831. ch: bch,
  832. style: {
  833. fg: 'black',
  834. inverse: inverse
  835. }
  836. });
  837. blessed.box({
  838. parent: symbols['m'],
  839. top: 0,
  840. right: 0,
  841. bottom: 0,
  842. width: wid,
  843. ch: bch,
  844. style: {
  845. fg: 'black',
  846. inverse: inverse
  847. }
  848. });
  849. blessed.box({
  850. parent: symbols['m'],
  851. top: 0,
  852. bottom: 0,
  853. left: 'center',
  854. width: wid,
  855. ch: bch,
  856. style: {
  857. fg: 'black',
  858. inverse: inverse
  859. }
  860. });
  861. symbols['m'].hide();
  862. }
  863. function updateTime() {
  864. var pos = 0
  865. , d = new Date
  866. , im = 'am'
  867. , time
  868. , h
  869. , m
  870. , s;
  871. h = d.getHours();
  872. if (h >= 12) {
  873. im = 'pm';
  874. }
  875. if (h > 12) {
  876. h -= 12;
  877. }
  878. if (h === 0) h = 12;
  879. if (h < 10) {
  880. h = '0' + h;
  881. }
  882. m = d.getMinutes();
  883. if (m < 10) {
  884. m = '0' + m;
  885. }
  886. s = d.getSeconds();
  887. if (s < 10) {
  888. s = '0' + s;
  889. }
  890. time = ~argv.indexOf('-s')
  891. ? h + ':' + m + ':' + s + im
  892. : h + ':' + m + im;
  893. if (time === lastTime) return;
  894. lastTime = time;
  895. time = time.split('');
  896. if (~argv.indexOf('-n')) {
  897. if (time[0] === '0') time[0] = ' ';
  898. }
  899. Object.keys(positions).forEach(function(key) {
  900. var symbols = positions[key];
  901. Object.keys(symbols).forEach(function(key) {
  902. symbols[key].hide();
  903. });
  904. });
  905. time.forEach(function(ch, i) {
  906. var symbols = positions[i]
  907. , symbol = symbols[ch];
  908. if (!symbol) return;
  909. symbol.rleft = pos;
  910. pos += symbol.width + 2;
  911. symbol.show();
  912. });
  913. if (~argv.indexOf('-d')) {
  914. date.show();
  915. date.setContent(d.toISOString().replace(/\.\d+/, ''));
  916. }
  917. screen.render();
  918. }
  919. setInterval(updateTime, ~argv.indexOf('-s') ? 100 : 950);
  920. updateTime();
  921. screen.key('q', function() {
  922. process.exit(0);
  923. });