New layout
[pysysbot:pysysbot.git] / src / pysysbot.py
1 #!/usr/bin/python
2 #
3 # pysysbot - A simple python jabber bot for getting system information
4 # Copyright (c) 2009 Fabian Affolter <fabian@bernewireless.net>
5 #
6 # All rights reserved.
7 #
8 # This program is free software; you can redistribute it and/or modify
9 # it under the terms of the GNU General Public License as published by
10 # the Free Software Foundation; either version 3 of the License, or
11 # (at your option) any later version.
12 #
13 # This program is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU General Public License for more details.
17 #
18 # You should have received a copy of the GNU General Public License
19 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 #
21 # Requires: python-jabberbot
22 #
23 from jabberbot import JabberBot, botcmd
24 import datetime
25 import os
26 import sys
27 import socket
28 import ConfigParser
29 import urllib2
30 import statgrab
31
32 __version__ = '0.2'
33
34
35 class pySysBot(JabberBot):
36     """
37     This is a simple Jabber bot that can show you some details and
38     information of the machine it is running on.
39     
40     Contact: You <you at some-domain.tld>
41     """
42     def top_of_help_message(self):
43         """Returns a string that forms the top of the help message"""
44         return "pySysBot"
45
46     def bottom_of_help_message(self):
47         """Returns a string that forms the bottom of the help message"""
48         return "Python %s / %s %s / %s %s" % \
49             ('.'.join([str(v) for v in sys.version_info[:3]]),
50              BOT_NAME,
51              __version__,
52              os.uname()[0],
53              os.uname()[2])
54
55 #Bot commands
56     @botcmd
57     def time( self, mess, args):
58         """Displays current server time"""
59         return datetime.datetime.today().strftime('%A, %d. %B %Y %H:%M:%S')
60
61     @botcmd
62     def uptime(self, mess, args):
63         """Displays the server uptime"""
64         uptime = open('/proc/uptime').read().split()[0]
65         # This is heavily based on the work of Hubert Chathi and his System status bot.
66         uptime = float(uptime)
67         (uptime,secs) = (int(uptime / 60), uptime % 60)
68         (uptime,mins) = divmod(uptime,60)
69         (days,hours) = divmod(uptime,24)
70
71         uptime = 'Uptime: %d day%s, %d hour%s %02d min%s' % (days, days != 1 
72             and 's' or '', hours, hours != 1 and 's' or '', mins,
73             mins != 1 and 's' or '')
74         return uptime
75
76     @botcmd
77     def server(self, mess, args):
78         """Displays server information"""
79         server = os.uname()
80         server_data = "System information" + \
81                 "\n" + " System: \t" + server[0] + \
82                 "\n" + " FQDN: \t"   + server[1] + \
83                 "\n" + " Kernel: \t" + server[2] + \
84                 "\n" + " Data: \t"   + server[3] + \
85                 "\n" + " Arch: \t"   + server[4]
86         return server_data
87
88     @botcmd
89     def load(self, mess, args):
90         """Displays the server load over the last 1, 5, and 15 minutes"""
91         loaddata = []
92         load = os.getloadavg()
93         for i in load:
94                 loaddata.append(i)
95         load_data = "Load average of the system" + \
96                 "\n" +"  1 min: \t" + str(loaddata[0]) + \
97                 "\n" +"  5 min: \t" + str(loaddata[1]) + \
98                 "\n" +" 15 min: \t" + str(loaddata[2])
99         return load_data
100
101     @botcmd
102     def processes(self, mess, args):
103         """Displays the processes of the server"""
104         process = statgrab.sg_get_process_count()
105         load_process = "Processes" + \
106                 "\n" + " Zombie: \t"   +  str(process['zombie'])  + \
107                 "\n" + " Running: \t"  + str(process['running'])  + \
108                 "\n" +  " Stopped: \t" + str(process['stopped'])  + \
109                 "\n" +" Sleeping: \t"  + str(process['sleeping']) + \
110                 "\n" + " Total: \t\t"  + str(process['total'])
111         return load_process
112
113     @botcmd
114     def mem(self, mess, args):
115         """Displays the memory status of the server"""
116         swapstat = statgrab.sg_get_swap_stats()
117         memstat = statgrab.sg_get_mem_stats()
118         #Some calculation to get the perc of the data
119         memdiff = memstat['total'] - memstat['free']
120         memfloat = float (memdiff) / float(memstat['total'])
121         memperc = int(round (memfloat * 100))
122         swapdiff = swapstat['total'] - swapstat['free']
123         swapfloat = float (swapdiff) / float(swapstat['total'])
124         swapperc = int(round (swapfloat * 100))
125         mem_process = "Memory status" + \
126                 "\n" + " Mem Total : \t" + str(memstat['total']/1048576) + \
127                 " MB \t \t Swap Total : \t" + str(swapstat['total']/1048576) + \
128                 " MB" + \
129                 "\n" + " Mem Used : \t" + str(memstat['used']/1048576) + \
130                 " MB \t \t Swap Used : \t" + str(swapstat['used']/1048576) + \
131                 " MB" + \
132                 "\n" + " Mem Free : \t" + str(memstat['free']/1048576)  + \
133                 " MB \t \t \t Swap Free : \t" + str(swapstat['free']/1048576) + \
134                 " MB" + "\n" + " Mem Used : \t" + str(memperc) + " %" + \
135                 " \t \t \t Swap Used : \t" + str(swapperc) + " %" 
136         return mem_process
137
138     @botcmd
139     def ip(self, mess, args):
140         """Displays the IP Addresses of the server"""
141         #Source: http://commandline.org.uk/python/how-to-find-out-ip-address-in-python/
142         s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
143         s.connect(('google.com', 0))
144         int_ipaddr=s.getsockname()[0]
145         ext_ipaddr = urllib2.urlopen("http://whatismyip.com/automation/n09230945.asp").read()
146         data_ipaddr = "Internal IP address: \t" + int_ipaddr + \
147                "\n" +"External IP address: \t" + ext_ipaddr
148         return data_ipaddr
149
150  
151 def read_config(file, config_jabber={}):
152     """
153     Read the configuration data from user's home directory.
154     Create an example file if it doesn't exist.
155     
156     Based on MythJabberbot (http://www.ian-barton.com/wiki/MythTV/MythJabberbot)
157     """
158     if not(os.path.exists(CONFIG_FILE)):
159         print '~/.my' + BOT_NAME + ' does not exist.'
160         configfile = open(CONFIG_FILE, "w")
161         configparse = ConfigParser.ConfigParser()
162         configparse.add_section(BOT_NAME)
163         print 'Please enter your jabber username and your password.'
164         username_in = raw_input('Username: ').strip()
165         password_in = raw_input('Password: ').strip()
166         if len(username_in) == 0 and len(password_in) == 0:
167             configparse.set(BOT_NAME, 'username', 'CHANGE_ME')
168             configparse.set(BOT_NAME, 'password', 'NOT_SET')
169             print 'Please edit ~/.my' + BOT_NAME + ' afterwards to match your'
170             print 'settings if you do not have a jabber account at the moment.'
171         else:
172             configparse.set(BOT_NAME, 'username', username_in)
173             configparse.set(BOT_NAME, 'password', password_in)
174             print '~/.my' + BOT_NAME + ' created.'
175         configparse.write(configfile)
176         configfile.close()
177         sys.exit()
178
179     else:
180         configparse = ConfigParser.ConfigParser()
181         configparse.read(file)
182         config_jabber['username'] = configparse.get(BOT_NAME, 'username')
183         config_jabber['password'] = configparse.get(BOT_NAME, 'password')
184         config_data.append(config_jabber)
185
186     return config_data
187
188 def main():
189     config = read_config(CONFIG_FILE)
190     bot = pySysBot(config[0]['username'], config[0]['password'])
191     bot.serve_forever()
192
193 if __name__ == '__main__':
194     BOT_NAME = 'pysysbot'
195     CONFIG_FILE = os.path.expanduser("~") + '/.my' + BOT_NAME
196     config_data = []
197     main()