1 # -*- coding: utf-8 -*-
3 # Copyright (c) 2010, 2011, 2013 Jack Kaliko <kaliko@azylum.org>
5 # This file is part of sima
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.
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.
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/>.
21 """generic tools and utilitaries for sima
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
31 def get_mpd_environ():
33 Retrieve MPD env. var.
36 mpd_host_env = environ.get('MPD_HOST')
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)
47 def normalize_path(path):
51 return normpath(join(getcwd(), path))
55 """Log unknown exceptions"""
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!')
67 class Obsolete(Action):
68 # pylint: disable=R0903
69 """Deal with obsolete arguments
71 def __call__(self, parser, namespace, values, option_string=None):
72 raise ArgumentError(self, 'obsolete argument')
74 class FileAction(Action):
75 """Generic class to inherit from for ArgParse action on file/dir
77 # pylint: disable=R0903
78 def __call__(self, parser, namespace, values, option_string=None):
79 self._file = normalize_path(values)
80 self._dir = dirname(self._file)
83 setattr(namespace, self.dest, self._file)
90 class Wfile(FileAction):
91 # pylint: disable=R0903
95 if not exists(self._dir):
96 #raise ArgumentError(self, '"{0}" does not exist'.format(self._dir))
97 self.parser.error('file does not exist: {0}'.format(self._dir))
98 if not exists(self._file):
99 # Is parent directory writable then
100 if not access(self._dir, W_OK):
101 self.parser.error('no write access to "{0}"'.format(self._dir))
103 if not access(self._file, W_OK):
104 self.parser.error('no write access to "{0}"'.format(self._file))
106 class Rfile(FileAction):
107 # pylint: disable=R0903
111 if not exists(self._file):
112 self.parser.error('file does not exist: {0}'.format(self._file))
113 if not isfile(self._file):
114 self.parser.error('not a file: {0}'.format(self._file))
115 if not access(self._file, R_OK):
116 self.parser.error('no read access to "{0}"'.format(self._file))
118 class Wdir(FileAction):
119 # pylint: disable=R0903
120 """Is directory writable
123 if not exists(self._file):
124 self.parser.error('directory does not exist: {0}'.format(self._file))
125 if not isdir(self._file):
126 self.parser.error('not a directory: {0}'.format(self._file))
127 if not access(self._file, W_OK):
128 self.parser.error('no write access to "{0}"'.format(self._file))
132 # vim: ai ts=4 sw=4 sts=4 expandtab