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 */ |
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'); |
988731c9 |
31 | var DBus = require('dbus-native'); |
c2c14655 |
32 | |
33 | /* setup indicator object */ |
34 | GNode.startLoop(); |
35 | Gtk.init(null); |
36 | var indicator = AppIndicator3.Indicator.new( |
37 | "lunar-indicator", |
9a229460 |
38 | __dirname + '/icons/鼠.svg', |
c2c14655 |
39 | AppIndicator3.IndicatorCategory.APPLICATION_STATUS |
40 | ); |
41 | indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE); |
42 | var menu = new Gtk.Menu(); |
43 | var item = new Gtk.MenuItem(); |
44 | menu.append(item); |
45 | indicator.set_menu(menu); |
46 | menu.show_all(); |
47 | |
48 | function 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 | |
79 | var job = new CronJob({ |
80 | cronTime: '0 * * * *', // every hour |
81 | onTick: update_indicator, |
82 | start: true |
83 | }); |
84 | |
85 | update_indicator(); |
988731c9 |
86 | |
87 | /* Detect resume from suspend and update date/time */ |
88 | var bus = DBus.systemBus(); |
89 | var service = bus.getService('org.freedesktop.login1'); |
90 | service.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 |
105 | Gtk.main(); |