]> kaliko git repositories - mpd-sima.git/blob - sima/utils/utils.py
Add conf management and cli parsing
[mpd-sima.git] / sima / utils / utils.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (c) 2010, 2011, 2013 Jack Kaliko <kaliko@azylum.org>
4 #
5 #  This file is part of sima
6 #
7 #  sima is free software: you can redistribute it and/or modify
8 #  it under the terms of the GNU General Public License as published by
9 #  the Free Software Foundation, either version 3 of the License, or
10 #  (at your option) any later version.
11 #
12 #  sima is distributed in the hope that it will be useful,
13 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #  GNU General Public License for more details.
16 #
17 #  You should have received a copy of the GNU General Public License
18 #  along with sima.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 #
21 """generic tools and utilitaries for sima
22 """
23
24 import traceback
25 import sys
26
27 from argparse import (ArgumentError, Action)
28 from os import (environ, access, getcwd, W_OK, R_OK)
29 from os.path import (dirname, isabs, join, normpath, exists, isdir, isfile)
30
31 def get_mpd_environ():
32     """
33     Retrieve MPD env. var.
34     """
35     passwd = host = None
36     mpd_host_env = environ.get('MPD_HOST')
37     if mpd_host_env:
38         # If password is set:
39         # mpd_host_env = ['pass', 'host'] because MPD_HOST=pass@host
40         mpd_host_env = mpd_host_env.split('@')
41         mpd_host_env.reverse()
42         host = mpd_host_env[0]
43         if len(mpd_host_env) > 1 and mpd_host_env[1]:
44             passwd = mpd_host_env[1]
45     return (host, environ.get('MPD_PORT', None), passwd)
46
47 def normalize_path(path):
48     """Get absolute path
49     """
50     if not isabs(path):
51         return normpath(join(getcwd(), path))
52     return path
53
54 def exception_log():
55     """Log unknown exceptions"""
56     import logging
57     log = logging.getLogger('sima')
58     log.error('Unhandled Exception!!!')
59     log.error(''.join(traceback.format_exc()))
60     log.info('Please report the previous message'
61              ' along with some log entries right before the crash.')
62     log.info('thanks for your help :)')
63     log.info('Quiting now!')
64     sys.exit(1)
65
66
67 # ArgParse Callbacks
68 class Obsolete(Action):
69     # pylint: disable=R0903
70     """Deal with obsolete arguments
71     """
72     def __call__(self, parser, namespace, values, option_string=None):
73         raise ArgumentError(self, 'obsolete argument')
74
75 class FileAction(Action):
76     """Generic class to inherit from for ARgPArse action on file/dir
77     """
78     # pylint: disable=R0903
79     def __call__(self, parser, namespace, values, option_string=None):
80         self._file = normalize_path(values)
81         self._dir = dirname(self._file)
82         self.parser = parser
83         self.checks()
84         setattr(namespace, self.dest, self._file)
85
86     def checks(self):
87         """control method
88         """
89         pass
90
91 class Wfile(FileAction):
92     # pylint: disable=R0903
93     """Is file writable
94     """
95     def checks(self):
96         if not exists(self._dir):
97             #raise ArgumentError(self, '"{0}" does not exist'.format(self._dir))
98             self.parser.error('file does not exist: {0}'.format(self._dir))
99         if not exists(self._file):
100             # Is parent directory writable then
101             if not access(self._dir, W_OK):
102                 self.parser.error('no write access to "{0}"'.format(self._dir))
103         else:
104             if not access(self._file, W_OK):
105                 self.parser.error('no write access to "{0}"'.format(self._file))
106
107 class Rfile(FileAction):
108     # pylint: disable=R0903
109     """Is file readable
110     """
111     def checks(self):
112         if not exists(self._file):
113             self.parser.error('file does not exist: {0}'.format(self._file))
114         if not isfile(self._file):
115             self.parser.error('not a file: {0}'.format(self._file))
116         if not access(self._file, R_OK):
117             self.parser.error('no read access to "{0}"'.format(self._file))
118
119 class Wdir(FileAction):
120     # pylint: disable=R0903
121     """Is directory writable
122     """
123     def checks(self):
124         if not exists(self._file):
125             self.parser.error('directory does not exist: {0}'.format(self._file))
126         if not isdir(self._file):
127             self.parser.error('not a directory: {0}'.format(self._file))
128         if not access(self._file, W_OK):
129             self.parser.error('no write access to "{0}"'.format(self._file))
130
131
132 # VIM MODLINE
133 # vim: ai ts=4 sw=4 sts=4 expandtab