| 1 | #!/usr/bin/env node |
| 2 | /* |
| 3 | * indicator-lunar-calendar - shows lunar calendar information |
| 4 | * Copyright (c) 2016 Adrian I Lam <adrianiainlam@gmail.com> |
| 5 | * |
| 6 | * Permission is hereby granted, free of charge, to any person obtaining a |
| 7 | * copy of this software and associated documentation files (the "Software"), |
| 8 | * to deal in the Software without restriction, including without limitation |
| 9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
| 10 | * and/or sell copies of the Software, and to permit persons to whom the |
| 11 | * Software is furnished to do so, subject to the following conditions: |
| 12 | * |
| 13 | * The above copyright notice and this permission notice shall be included in |
| 14 | * all copies or substantial portions of the Software. |
| 15 | * |
| 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| 19 | * THE AUTHOR OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
| 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
| 21 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
| 22 | * IN THE SOFTWARE. |
| 23 | */ |
| 24 | |
| 25 | /* import dependencies */ |
| 26 | var GNode = require('node-gtk'); |
| 27 | var Gtk = GNode.importNS('Gtk'); |
| 28 | var AppIndicator3 = GNode.importNS('AppIndicator3'); |
| 29 | var CronJob = require('cron').CronJob; |
| 30 | var LunarCalendar = require('lunar-calendar-zh'); |
| 31 | |
| 32 | /* setup indicator object */ |
| 33 | GNode.startLoop(); |
| 34 | Gtk.init(null); |
| 35 | var indicator = AppIndicator3.Indicator.new( |
| 36 | "lunar-indicator", |
| 37 | __dirname + '/鼠.svg', |
| 38 | AppIndicator3.IndicatorCategory.APPLICATION_STATUS |
| 39 | ); |
| 40 | indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE); |
| 41 | var menu = new Gtk.Menu(); |
| 42 | var item = new Gtk.MenuItem(); |
| 43 | menu.append(item); |
| 44 | indicator.set_menu(menu); |
| 45 | menu.show_all(); |
| 46 | |
| 47 | function update_indicator() { |
| 48 | /* get current time at UTC+8, add 1 to date if after 23:00 (子時) */ |
| 49 | var now = new Date(new Date().getTime() + 8 * 3600 * 1000); |
| 50 | var hour = now.getUTCHours(); |
| 51 | if(hour >= 23) { // 子時 of the next day |
| 52 | now = new Date(now.getTime() + 24 * 3600 * 1000); |
| 53 | } |
| 54 | var year = now.getUTCFullYear(); |
| 55 | var month = now.getUTCMonth() + 1; |
| 56 | var day = now.getUTCDate(); |
| 57 | |
| 58 | /* obtain date/time in lunar calendar */ |
| 59 | var lunar = LunarCalendar.solarToLunar(year, month, day); |
| 60 | lunar.hour = '子丑寅卯辰巳午未申酉戌亥'[Math.floor((hour + 1) % 24 / 2)]; |
| 61 | |
| 62 | /* output formatting */ |
| 63 | var compact_date = lunar.lunarMonthName + lunar.lunarDayName; |
| 64 | var long_date = lunar.GanZhiYear + '年(' + lunar.zodiac + '年)\n' + |
| 65 | lunar.lunarMonthName + lunar.lunarDayName; |
| 66 | if(lunar.term) { // add solar term (節氣) to output if at solar term |
| 67 | compact_date += ' ' + lunar.term; |
| 68 | long_date += ' ' + lunar.term; |
| 69 | } |
| 70 | long_date += '\n' + lunar.hour + '時'; |
| 71 | |
| 72 | /* output to indicator */ |
| 73 | indicator.set_icon(__dirname + '/' + lunar.zodiac + '.svg'); |
| 74 | indicator.set_label(compact_date, ''); |
| 75 | item.set_label(long_date); |
| 76 | } |
| 77 | |
| 78 | var job = new CronJob({ |
| 79 | cronTime: '0 * * * *', // every hour |
| 80 | onTick: update_indicator, |
| 81 | start: true |
| 82 | }); |
| 83 | |
| 84 | update_indicator(); |
| 85 | Gtk.main(); |