Gnome SHELL Generic Monitor

Gnome SHELL Generic Monitor Git Source Tree

Root/examples/mail.py

1#!/usr/bin/python3
2
3#
4# This program is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program. If not, see <https://www.gnu.org/licenses/>.
16#
17
18'''
19Display number of mail from gmail account and Pidgin icon if there is some unread Pidgin message
20'''
21
22import time
23import requests
24from requests.auth import HTTPBasicAuth
25import xml.dom.minidom
26from threading import Thread
27from signal import signal, SIGINT
28import sys
29from genericmonitor import *
30from gmail import getUnreadMails
31
32PURPLE_CONV_UPDATE_UNSEEN = 4
33PURPLE_MESSAGE_SEND = 0
34
35class PidginConversation:
36 STATUS_SEEN = 0
37 STATUS_UNSEEN = 1
38
39 def __init__(self, _id):
40 self._id = _id
41 self.status = PidginConversation.STATUS_SEEN
42 self.nbMessages = 1
43
44 def updateNbMessages(self):
45 self.nbMessages += 1
46 # Status is seen until it changes
47 self.status = PidginConversation.STATUS_SEEN
48
49 def setSeen(self):
50 self.status = PidginConversation.STATUS_SEEN
51
52 def setUnseen(self):
53 self.nbMessages = 0
54 self.status = PidginConversation.STATUS_UNSEEN
55
56 def isSeen(self):
57 return (self.status == PidginConversation.STATUS_SEEN)
58
59
60class EventThread(Thread,GenericMonitor):
61 SLEEP_TIME = 30
62
63 def stop(self):
64 self._stopLoop = True
65 self.stopMainLoop()
66
67 def _getMail(self):
68 text = ''
69 style = ''
70 try:
71 nb_messages = getUnreadMails()
72 if nb_messages == 1:
73 text = '1 msg'
74 elif nb_messages > 1:
75 text = '%d msgs' % (nb_messages)
76 style = 'color:white'
77 except Exception as e:
78 text = str(e)
79
80 self.mailWidget.setText(text)
81 self.mailWidget.setStyle(style)
82 self.notify(self.mailGroup)
83
84 def getEvents(self):
85 self._getMail()
86
87 def run(self):
88 self._stopLoop = False
89 self.setupMonitor()
90 self.pidgin_conversations = {}
91
92 self.add_signal_receiver(self.pidginMessageReceived, 'ReceivedImMsg', 'im.pidgin.purple.PurpleInterface')
93 self.add_signal_receiver(self.pidginMessageReceived, 'ReceivedChatMsg', 'im.pidgin.purple.PurpleInterface')
94 self.add_signal_receiver(self.pidginMessageWrote, 'WroteImMsg', 'im.pidgin.purple.PurpleInterface')
95 self.add_signal_receiver(self.pidginMessageWrote, 'WroteChatMsg', 'im.pidgin.purple.PurpleInterface')
96 self.add_signal_receiver(self.pidginConversationUpdated, 'ConversationUpdated', 'im.pidgin.purple.PurpleInterface')
97
98 self.mailWidget = GenericMonitorTextWidget('')
99 mailItem = GenericMonitorItem('mail', [self.mailWidget])
100 self.mailGroup = GenericMonitorGroup('Mail', [mailItem])
101
102 icon = GenericMonitorIconWidget('/usr/share/icons/hicolor/22x22/apps/pidgin.png', 'icon-size:22px')
103 pidginItem = GenericMonitorItem('pidgin', [icon])
104 self.pidginGroup = GenericMonitorGroup('Pidgin', pidginItem)
105
106 while not self._stopLoop:
107 self.getEvents()
108 # Be more reactive on signal capture
109 for i in range(0, self.SLEEP_TIME):
110 if self._stopLoop: break
111 time.sleep(1)
112
113 def pidginMessageReceived(self, account, sender, message, conversation, flags):
114 pidginConversation = self.pidgin_conversations.get(conversation, None)
115 if not pidginConversation:
116 self.pidgin_conversations[conversation] = PidginConversation(conversation)
117 else:
118 pidginConversation.updateNbMessages()
119
120 def pidginMessageWrote(self, account, sender, message, conversation, flags):
121 if not (flags & (1 << PURPLE_MESSAGE_SEND)):
122 return
123 pidginConversation = self.pidgin_conversations.get(conversation, None)
124 if not pidginConversation:
125 self.pidgin_conversations[conversation] = PidginConversation(conversation)
126 pidginConversation = self.pidgin_conversations[conversation]
127 pidginConversation.setSeen()
128 pidginConversation.nbMessages = 1
129
130 def displayIcon(self):
131 self.notify(self.pidginGroup)
132
133 def pidginConversationUpdated(self, conversation, _type):
134 if _type != PURPLE_CONV_UPDATE_UNSEEN:
135 return
136
137 pidginConversation = self.pidgin_conversations.get(conversation, None)
138 if not pidginConversation:
139 return
140
141 if pidginConversation.isSeen():
142 if pidginConversation.nbMessages > 0:
143 pidginConversation.setUnseen()
144 else:
145 pidginConversation.setSeen()
146
147 # Message not seen by user
148 if not pidginConversation.isSeen():
149 self.displayIcon()
150 else:
151 deleteIcon = True
152 # Are all messages seen ?
153 for pConv in self.pidgin_conversations.values():
154 if not pConv.isSeen():
155 deleteIcon = False
156 break
157 if deleteIcon:
158 items = {'items':['pidgin@Pidgin']}
159 self.deleteItems(items)
160
161 def onActivate(self):
162 super().onActivate()
163 for pConv in self.pidgin_conversations.values():
164 if not pConv.isSeen():
165 self.displayIcon()
166 break
167
168def signalHandler(signal_received, frame):
169 eventThread.stop()
170 eventThread.join()
171 groups = ['Mail', 'Pidgin']
172 eventThread.deleteGroups(groups)
173 sys.exit(0)
174
175eventThread = EventThread()
176eventThread.start()
177
178signal(SIGINT, signalHandler)
179
180eventThread.runMainLoop()

Archive Download this file

Branches

Tags