Support errbot 5 and python 3
[errbot-exec.git] / exec.py
1 # -*- coding: utf-8 -*-
2 import os, re, subprocess
3 from errbot import BotPlugin, botcmd, re_botcmd, ValidationException
4
5 class Exec(BotPlugin):
6     """
7     Execute a command when the bot is talked to
8     """
9
10     config_template = {
11         'command': u'echo'
12     }
13
14     def activate(self):
15         """
16         Load configuration from config.by
17         """
18         super(Exec, self).activate()
19         if (self.config == None and self.bot_config.EXEC):
20             self.check_configuration(self.bot_config.EXEC)
21             self.configure(self.bot_config.EXEC)
22
23     def executable_exists(self, name):
24         """
25         Check if an executable exists
26         """
27         if len(name) == 0:
28             raise ValidationException('Command is empty')
29
30         if os.path.exists(name):
31             return
32
33         found = False
34         for path in os.environ['PATH'].split(os.pathsep):
35             fullpath = path + os.sep + name
36             if os.path.exists(fullpath):
37                 found = True
38                 break
39         if not found:
40             raise ValidationException('Command not in PATH')
41
42     def get_configuration_template(self):
43         """
44         Defines the configuration structure this plugin supports
45         """
46         return self.config_template
47
48     def check_configuration(self, configuration):
49         """
50         Triggers when the configuration is checked, shortly before activation
51         """
52         super(Exec, self).check_configuration(configuration)
53         self.executable_exists(configuration['command'])
54
55     @re_botcmd(pattern=r".*", prefixed=False)
56     def runexec(self, msg, match):
57         """
58         Execute the commmand
59         """
60         try:
61             output = subprocess.check_output(
62                 [self.config['command'], msg.body, str(msg.frm)],
63                 stderr=subprocess.STDOUT
64             )
65             if len(output) > 0:
66                 return str(output, 'utf-8')
67             else:
68                 return "OK\n"
69         except subprocess.CalledProcessError as err:
70             if len(err.output):
71                 return str(err.output, 'utf-8')
72             else:
73                 return "Error"