-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindicator.py
executable file
·167 lines (137 loc) · 6.11 KB
/
indicator.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk as Gtk
from gi.repository import GLib as GLib
gi.require_version('AppIndicator3', '0.1')
# gi.require_version('AppIndicator7', '1')
# import appindicator
from gi.repository import AppIndicator3 as AppIndicator
import sys
import os
import re
import logging
import math
import argparse
import signal
def signal_handler(sig, frame):
print('You pressed Ctrl+C!')
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
parser = argparse.ArgumentParser(description='Initialize a unity lsyncd indicator')
parser.add_argument('-l', '--loglevel', dest='loglevel', help='Options: DEBUG, INFO, WARNING, ERROR, CRITCAL')
args = parser.parse_args()
numeric_level = 50
if (args.loglevel):
numeric_level = getattr(logging, args.loglevel.upper(), None)
if not isinstance(numeric_level, int):
print ("Incorrect parameter for loglevel. Defaulting to WARNING")
numeric_level = 30 # Default to warnings
logging.basicConfig(level=numeric_level)
class LsyncdIndicator:
def __init__(self):
self.ind = AppIndicator.Indicator.new_with_path(
"my-custom-indicator",
"bluespinner",
AppIndicator.IndicatorCategory.APPLICATION_STATUS,
os.path.dirname(os.path.realpath(__file__)) + '/icons/')
self.menu_setup()
self.ind.set_menu(self.menu)
self.lastSeekPosition = 0
self.syncQueue = []
self.lineType = ''
self.indicatorIconIndex = 1
def menu_setup(self):
self.menu = Gtk.Menu()
self.quit_item = Gtk.MenuItem(label="Quit")
self.quit_item.connect("activate", self.quit)
self.quit_item.show()
self.test_item = Gtk.MenuItem(label="Open Config")
self.test_item.connect("activate", self.open_config)
self.test_item.show()
self.menu.append(self.test_item)
self.menu.append(self.quit_item)
# self.ind.set_label('lsyncd', 'LSYNCD')
def main(self):
self.logfile = open('/var/log/lsyncd/lsyncd.log', mode='rb')
GLib.timeout_add(200, self.monitor_lsyncd)
GLib.MainLoop().run()
def quit(self, menuObj):
GLib.MainLoop().quit()
sys.exit(0)
def open_config(test, test1):
os.system('xdg-open "' + os.environ['HOME'] + '/.config/lsyncd/config.lua"')
def monitor_lsyncd(self):
lastLine = self.tail_log()
self.update_indicator_index()
logging.debug("Queue: " + self.lineType + " " + str(self.syncQueue) + " " + os.path.dirname(os.path.realpath(__file__)))
# Found a match that a sync is happening
if (self.lineType == 'FINISHED' and len(self.syncQueue) == 0):
self.ind.set_status(AppIndicator.IndicatorStatus.ACTIVE)
self.ind.set_icon_full('greyspinner' + str(math.ceil(self.indicatorIconIndex / 4)), "Done syncing")
elif (self.lineType == 'FINISHED' and len(self.syncQueue) > 0):
# print("in case 2", file=sys.stderr)
pass
elif (self.lineType == 'SYNCING'):
# print("in case 3", file=sys.stderr)
self.ind.set_icon_full('greenspinner' + str(math.ceil(self.indicatorIconIndex % 4) + 1), "Actively syncing")
self.ind.set_status(AppIndicator.IndicatorStatus.ATTENTION)
elif (self.lineType == 'LSYNCD TERMINATED'):
# print("in case 4", file=sys.stderr)
self.ind.set_icon_full('redep', "No lsyncd process found")
self.ind.set_status(AppIndicator.IndicatorStatus.ATTENTION)
elif (self.lineType == 'ERROR'):
print("in case 5", file=sys.stderr)
self.ind.set_icon_full('redep', "Unhandled Error")
self.ind.set_status(AppIndicator.IndicatorStatus.ATTENTION)
else:
print("in case 6", file=sys.stderr)
logging.warning("unknown something happening. Update some regular expressions")
return True
def update_indicator_index(self):
if (self.indicatorIconIndex >= 16):
self.indicatorIconIndex = 1
else:
self.indicatorIconIndex = self.indicatorIconIndex + 1
def tail_log(self):
# Keep track of the number of bytes has been written to the log file since the last loop
amountToSeek = 0
endOfFileByte = self.logfile.seek(0, 2)
if (self.lastSeekPosition != endOfFileByte):
amountToSeek = self.logfile.tell() - self.lastSeekPosition
self.lastSeekPosition = self.logfile.tell()
# If this is the first run, the amount to seek will be the entire file.
if (self.lastSeekPosition != amountToSeek):
self.logfile.seek(-amountToSeek, 1)
elif (self.lastSeekPosition == amountToSeek):
self.logfile.seek(-200, 2)
line = self.logfile.readline().decode().rstrip()
lastLine = line
while line != '':
lastLine = line
self.lastSeekPosition = self.logfile.tell()
self.lineType = self.get_type_of_line(line);
if (self.lineType == 'FINISHED' and len(self.syncQueue) > 0):
self.syncQueue.pop()
elif (self.lineType == 'ERROR'):
self.syncQueue = []
elif (self.lineType == 'STARTING SYNC'):
self.syncQueue.append(self.lineType)
line = self.logfile.readline().decode().rstrip()
return lastLine
def get_type_of_line(self, lastLine):
if (re.search('exitcode: 0$', lastLine) or re.search('finished\.$', lastLine) or re.search('some files vanished', lastLine)):
return 'FINISHED'
elif (re.search('Calling rsync with', lastLine) or re.search('recursive startup rsync', lastLine)):
return 'STARTING SYNC'
elif (re.search('/$', lastLine) or re.search('[\*\w]\.\w+$', lastLine)):
return 'SYNCING'
elif (re.search('TERM signal, fading ---', lastLine)):
return 'LSYNCD TERMINATED'
elif (re.search('error|Error', lastLine)):
return 'ERROR'
else:
return 'UNKNOWN'
if __name__ == "__main__":
indicator = LsyncdIndicator()
indicator.main()