Ticket #4600: MythDB.py

File MythDB.py, 4.6 KB (added by trisooma, 13 years ago)

Database component

Line 
1#!/usr/bin/python
2
3# vim:ts=4 sw=4 nowrap:
4
5# system imports
6import os
7import sys
8import shlex
9import code
10import getopt
11from datetime import datetime
12# MythTV imports
13from MythLog import *
14
15
16# create logging object
17log = MythLog(INFO, '%(levelname)s - %(message)s', 'MythDB')
18
19# check for dependency
20try:
21        import MySQLdb
22except:
23        log.Msg(CRITICAL, "MySQLdb (python-mysqldb) is required but is not found.")
24        sys.exit(1)
25
26
27
28class MythDB:
29        """
30        A connection to the mythtv database.
31        """
32        def __init__(self, args):
33                # Setup connection variables
34                dbconn = {
35                        'host'  : None,
36                        'name'  : None,
37                        'user'  : None,
38                        'pass'  : None
39                }
40               
41                # Try to read the mysql.txt file used by MythTV.
42                # Order taken from libs/libmyth/mythcontext.cpp
43                config_files = [
44                        '/usr/local/share/mythtv/mysql.txt',
45                        '/usr/share/mythtv/mysql.txt',
46                        '/usr/local/etc/mythtv/mysql.txt',
47                        '/etc/mythtv/mysql.txt',
48                        os.path.expanduser('~/.mythtv/mysql.txt'),
49                ]
50                if 'MYTHCONFDIR' in os.environ:
51                        config_locations.append('%s/mysql.txt' % os.environ['MYTHCONFDIR'])
52               
53                found_config = False
54                for config_file in config_files:
55                        try:
56                                config = shlex.shlex(open(config_file))
57                                config.wordchars += "."
58                        except:
59                                continue
60       
61                        dbconn['host'] = None
62                        dbconn['name'] = None
63                        dbconn['user'] = None
64                        dbconn['pass'] = None
65                        token = config.get_token()
66                        while  token != config.eof and not found_config:
67                                if token == "DBHostName":
68                                        if config.get_token() == "=":
69                                                dbconn['host'] = config.get_token()
70                                elif token == "DBName":
71                                        if config.get_token() == "=":
72                                                dbconn['name'] = config.get_token()
73                                elif token == "DBUserName":
74                                        if config.get_token() == "=":
75                                                dbconn['user'] = config.get_token()
76                                elif token == "DBPassword":
77                                        if config.get_token() == "=":
78                                                dbconn['pass'] = config.get_token()
79                                token = config.get_token()
80                        if dbconn['host'] != None and dbconn['name'] != None and dbconn['user'] != None and dbconn['pass'] != None:
81                                log.Msg(INFO, 'Using config %s', config_file)
82                                found_config = True
83                                break
84
85                # Overrides from command line parameters
86                try:
87                opts, args = getopt.getopt(args, '', ['dbhost=', 'user=', 'pass=', 'database='])
88                        for o, a in opts:
89                                if o == '--dbhost':
90                                        dbconn['host'] = a
91                                if o == '--user':
92                                        dbconn['user'] = a
93                                if o == '--pass':
94                                        dbconn['pass'] = a
95                                if o == '--database':
96                                        dbconn['name'] = a
97        except:
98                        pass
99
100                if not dbconn['host'] and not found_config:
101                        raise MythError('Unable to find MythTV configuration file')
102
103                try:
104                        self.db = MySQLdb.connect(user=dbconn['user'], host=dbconn['host'], passwd=dbconn['pass'], db=dbconn['name'])
105                        log.Msg(INFO, 'DB Connection info (host:%s, name:%s, user:%s, pass:%s)', dbconn['host'], dbconn['name'], dbconn['user'], dbconn['pass'])
106                except:
107                        raise MythError('Connection failed for \'%s\'@\'%s\' to database %s using password %s' % (dbconn['user'], dbconn['host'], dbconn['name'], dbconn['pass']))
108
109
110
111        def getAllSettings(self, hostname=None):
112                """
113                Returns values for all settings.
114               
115                Returns None if there are no settings. If multiple rows are
116                found (multiple hostnames), returns the value of the first one.
117                """
118                log.Msg(DEBUG, 'Retrieving all setting for host %s', hostname)
119                c = self.db.cursor()
120                if hostname is None:
121                        c.execute("""
122                                SELECT value, data
123                                FROM settings
124                                WHERE hostname IS NULL""")
125                else:
126                        c.execute("""
127                                SELECT value, data
128                                FROM settings
129                                WHERE hostname LIKE('%s%%')""" %
130                                (hostname)
131                        )
132                rows = c.fetchall()
133                c.close()
134               
135                if rows:
136                        return rows
137                else:
138                        return None
139
140
141
142        def getSetting(self, value, hostname=None):
143                """
144                Returns the value for the given MythTV setting.
145               
146                Returns None if the setting was not found. If multiple rows are
147                found (multiple hostnames), returns the value of the first one.
148                """
149                log.Msg(DEBUG, 'Looking for setting %s for host %s', value, hostname)
150                c = self.db.cursor()
151                if hostname is None:
152                        c.execute("""
153                                SELECT data
154                                FROM settings
155                                WHERE value LIKE('%s') AND hostname IS NULL LIMIT 1""" %
156                                (value))
157                else:
158                        c.execute("""
159                                SELECT data
160                                FROM settings
161                                WHERE value LIKE('%s') AND hostname LIKE('%s%%') LIMIT 1""" %
162                                (value, hostname))
163                row = c.fetchone()
164                c.close()
165               
166                if row:
167                        return row[0]
168                else:
169                        return None
170
171
172       
173        def cursor(self):
174                return self.db.cursor()
175
176       
177
178if __name__ == '__main__':
179        banner = "'mdb' is a MythDB instance."
180        try:
181                import readline, rlcompleter
182        except:
183                pass
184        else:
185                readline.parse_and_bind("tab: complete")
186                banner = banner + " TAB completion is available."
187        mdb = MythDB(sys.argv[1:])
188        namespace = globals().copy()
189        namespace.update(locals())
190        code.InteractiveConsole(namespace).interact(banner)