summaryrefslogtreecommitdiff
path: root/client/diagnose.py
blob: 28cd9c8b16f428be0265f4cae0d90b1bcafd5383 (plain)
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
#!/usr/bin/env python2
import time
import re
import socket
import os
from subprocess import check_output, call
import jasperpath

class Diagnostics:

    """
    Set of diagnostics to be run for determining the health of the
    host running Jasper

    To add new checks, add a boolean returning method with a name that starts
    with `check_`
    """

    @classmethod
    def check_network_connection(cls):
        try:
            # see if we can resolve the host name -- tells us if there is
            # a DNS listening
            host = socket.gethostbyname("www.google.com")
            # connect to the host -- tells us if the host is actually
            # reachable
            socket.create_connection((host, 80), 2)
        except Exception:
            return False
        else:
            return True

    @classmethod
    def check_phonetisaurus_dictionary_file(cls):
        return os.path.isfile(os.path.join(jasperpath.APP_PATH, "..", "phonetisaurus/g014b2b.fst"))

    @classmethod
    def check_phonetisaurus_program(cls):
        return call(['which', 'phonetisaurus-g2p']) == 0

    @classmethod
    def info_git_revision(cls):
        return check_output(['git', 'rev-parse', 'HEAD'])


class DiagnosticRunner:

    """
    Performs a series of checks against the system, printing the results to the
    console and also saving them to diagnostic.log
    """

    def __init__(self, diagnostics):
        self.diagnostics = diagnostics

    def run(self):
        self.initialize_log()
        self.perform_checks()

    def perform_checks(self):
        self.failed_checks = 0
        for check in self.select_methods('check'):
            self.do_check(check)
        for info in self.select_methods('info'):
            self.get_info(info)
        if self.failed_checks == 0:
            self.log("All checks passed\n")
        else:
            self.log("%d checks failed\n" % self.failed_checks)

    def select_methods(self, prefix):
        def is_match(method_name):
            return callable(getattr(self.diagnostics, method_name)) and re.match(r"\A" + prefix + "_", method_name)

        return [method_name for method_name in dir(self.diagnostics) if is_match(method_name)]

    def initialize_log(self):
        self.output = open('diagnostic.log', 'w')
        self.log("Starting jasper diagnostic\n")
        self.log(time.strftime("%c") + "\n")

    def log(self, msg):
        print msg,
        self.output.write(msg)

    def get_info(self, info_name):
        message = info_name.replace("info_", "").replace("_", " ")
        info_method = getattr(self.diagnostics, info_name)
        info = info_method()
        self.log("%s: %s" % (message, info))

    def do_check(self, check_name):
        message = check_name.replace("check_", "").replace("_", " ")
        check = getattr(self.diagnostics, check_name)
        self.log("Checking %s... " % message)
        if check():
            self.log("OK")
        else:
            self.failed_checks += 1
            self.log("FAILED")
        self.log("\n")


if __name__ == '__main__':
    DiagnosticRunner(Diagnostics).run()