]> kaliko git repositories - mpd-sima.git/blob - sima/utils/utils.py
Plain api keys obfuscation
[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 utilities for sima
22 """
23
24 import traceback
25 import sys
26
27 from argparse import ArgumentError, Action
28 from base64 import b64decode as push
29 from codecs import getencoder
30 from os import environ, access, getcwd, W_OK, R_OK
31 from os.path import dirname, isabs, join, normpath, exists, isdir, isfile
32
33
34 def getws(dic):
35     """
36     Decode Obfuscated api key.
37     Only preventing API keys harvesting over the network
38     https://developer.echonest.com/forums/thread/105
39     """
40     aka = push(bytes(dic.get('apikey') + '=', 'utf-8'))
41     aka = getencoder('rot-13')(str((aka), 'utf-8'))[0]
42     dic.update({'apikey':aka})
43
44 def get_mpd_environ():
45     """
46     Retrieve MPD env. var.
47     """
48     passwd = host = None
49     mpd_host_env = environ.get('MPD_HOST')
50     if mpd_host_env:
51         # If password is set:
52         # mpd_host_env = ['pass', 'host'] because MPD_HOST=pass@host
53         mpd_host_env = mpd_host_env.split('@')
54         mpd_host_env.reverse()
55         host = mpd_host_env[0]
56         if len(mpd_host_env) > 1 and mpd_host_env[1]:
57             passwd = mpd_host_env[1]
58     return (host, environ.get('MPD_PORT', None), passwd)
59
60 def normalize_path(path):
61     """Get absolute path
62     """
63     if not isabs(path):
64         return normpath(join(getcwd(), path))
65     return path
66
67 def exception_log():
68     """Log unknown exceptions"""
69     import logging
70     log = logging.getLogger('sima')
71     log.error('Unhandled Exception!!!')
72     log.error(''.join(traceback.format_exc()))
73     log.info('Please report the previous message'
74              ' along with some log entries right before the crash.')
75     log.info('thanks for your help :)')
76     log.info('Quiting now!')
77     sys.exit(1)
78
79 class SigHup(Exception):
80     pass
81
82 # ArgParse Callbacks
83 class Obsolete(Action):
84     # pylint: disable=R0903
85     """Deal with obsolete arguments
86     """
87     def __call__(self, parser, namespace, values, option_string=None):
88         raise ArgumentError(self, 'obsolete argument')
89
90 class FileAction(Action):
91     """Generic class to inherit from for ArgParse action on file/dir
92     """
93     # pylint: disable=R0903
94     def __call__(self, parser, namespace, values, option_string=None):
95         self._file = normalize_path(values)
96         self._dir = dirname(self._file)
97         self.parser = parser
98         self.checks()
99         setattr(namespace, self.dest, self._file)
100
101     def checks(self):
102         """control method
103         """
104         pass
105
106 class Wfile(FileAction):
107     # pylint: disable=R0903
108     """Is file writable
109     """
110     def checks(self):
111         if not exists(self._dir):
112             #raise ArgumentError(self, '"{0}" does not exist'.format(self._dir))
113             self.parser.error('file does not exist: {0}'.format(self._dir))
114         if not exists(self._file):
115             # Is parent directory writable then
116             if not access(self._dir, W_OK):
117                 self.parser.error('no write access to "{0}"'.format(self._dir))
118         else:
119             if not access(self._file, W_OK):
120                 self.parser.error('no write access to "{0}"'.format(self._file))
121
122 class Rfile(FileAction):
123     # pylint: disable=R0903
124     """Is file readable
125     """
126     def checks(self):
127         if not exists(self._file):
128             self.parser.error('file does not exist: {0}'.format(self._file))
129         if not isfile(self._file):
130             self.parser.error('not a file: {0}'.format(self._file))
131         if not access(self._file, R_OK):
132             self.parser.error('no read access to "{0}"'.format(self._file))
133
134 class Wdir(FileAction):
135     # pylint: disable=R0903
136     """Is directory writable
137     """
138     def checks(self):
139         if not exists(self._file):
140             self.parser.error('directory does not exist: {0}'.format(self._file))
141         if not isdir(self._file):
142             self.parser.error('not a directory: {0}'.format(self._file))
143         if not access(self._file, W_OK):
144             self.parser.error('no write access to "{0}"'.format(self._file))
145
146
147 # VIM MODLINE
148 # vim: ai ts=4 sw=4 sts=4 expandtab