fix time inaccuracy due to suspend/resume
[indicator-lunar-calendar.git] / indicator-lunar-calendar.js
CommitLineData
c2c14655 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 */
26var GNode = require('node-gtk');
27var Gtk = GNode.importNS('Gtk');
28var AppIndicator3 = GNode.importNS('AppIndicator3');
29var CronJob = require('cron').CronJob;
30var LunarCalendar = require('lunar-calendar-zh');
988731c9 31var DBus = require('dbus-native');
c2c14655 32
33/* setup indicator object */
34GNode.startLoop();
35Gtk.init(null);
36var indicator = AppIndicator3.Indicator.new(
37 "lunar-indicator",
9a229460 38 __dirname + '/icons/鼠.svg',
c2c14655 39 AppIndicator3.IndicatorCategory.APPLICATION_STATUS
40);
41indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE);
42var menu = new Gtk.Menu();
43var item = new Gtk.MenuItem();
44menu.append(item);
45indicator.set_menu(menu);
46menu.show_all();
47
48function update_indicator() {
49 /* get current time at UTC+8, add 1 to date if after 23:00 (子時) */
50 var now = new Date(new Date().getTime() + 8 * 3600 * 1000);
51 var hour = now.getUTCHours();
52 if(hour >= 23) { // 子時 of the next day
53 now = new Date(now.getTime() + 24 * 3600 * 1000);
54 }
55 var year = now.getUTCFullYear();
56 var month = now.getUTCMonth() + 1;
57 var day = now.getUTCDate();
58
59 /* obtain date/time in lunar calendar */
60 var lunar = LunarCalendar.solarToLunar(year, month, day);
61 lunar.hour = '子丑寅卯辰巳午未申酉戌亥'[Math.floor((hour + 1) % 24 / 2)];
62
63 /* output formatting */
64 var compact_date = lunar.lunarMonthName + lunar.lunarDayName;
65 var long_date = lunar.GanZhiYear + '年(' + lunar.zodiac + '年)\n' +
66 lunar.lunarMonthName + lunar.lunarDayName;
67 if(lunar.term) { // add solar term (節氣) to output if at solar term
68 compact_date += ' ' + lunar.term;
69 long_date += ' ' + lunar.term;
70 }
71 long_date += '\n' + lunar.hour + '時';
72
73 /* output to indicator */
9a229460 74 indicator.set_icon(__dirname + '/icons/' + lunar.zodiac + '.svg');
c2c14655 75 indicator.set_label(compact_date, '');
76 item.set_label(long_date);
77}
78
79var job = new CronJob({
80 cronTime: '0 * * * *', // every hour
81 onTick: update_indicator,
82 start: true
83});
84
85update_indicator();
988731c9 86
87/* Detect resume from suspend and update date/time */
88var bus = DBus.systemBus();
89var service = bus.getService('org.freedesktop.login1');
90service.getInterface(
91 '/org/freedesktop/login1',
92 'org.freedesktop.login1.Manager',
93 function(err, nm) {
94 nm.addListener('PrepareForSleep', function(arg) {
95 // PrepareForSleep returns false when resuming from suspend
96 if(!arg) {
97 job.stop(); // force cronjob to recalculate time
98 job.start();
99 update_indicator();
100 }
101 });
102 }
103);
104
c2c14655 105Gtk.main();