forked from haydnw/AirPi
-
Notifications
You must be signed in to change notification settings - Fork 0
/
plugin.py
executable file
·205 lines (167 loc) · 6.82 KB
/
plugin.py
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
"""Generic AirPi plugin description (abstract) for sub-classing.
A generic description of an AirPi plugin, which can then be sub-classed
for more specific purposes. This is an abstract base class (ABC) and so cannot
be instantiated directly.
"""
from abc import ABCMeta, abstractmethod
import socket
import ConfigParser
import os
import urllib2
class Plugin(object):
"""Generic AirPi plugin description (abstract) for sub-classing.
A generic description of an AirPi plugin, which can then be sub-classed
for more specific purposes. This is an abstract base class (ABC) and so cannot
be instantiated directly.
"""
__metaclass__ = ABCMeta
requiredGenericParams = None
optionalGenericParams = ["target"]
requiredSpecificParams = None
optionalSpecificParams = None
commonParams = None
def __init__(self, config, purpose):
self.name = type(self).__name__
self.purpose = purpose
#TODO: Is self.async really required?
self.async = False
self.params = {}
if self.setallparams(config):
if ("target" in self.params and self.params["target"] == "internet") and not self.check_conn():
msg = "Skipping " + self.purpose + " plugin " + self.name
msg += " because no internet connectivity."
#msg = format_msg(msg, 'error')
print(msg)
#logthis("info", msg)
raise NoInternetConnection
else:
msg = "Failed to set parameters for " + self.purpose + " plugin " + self.name
print(msg)
#logthis("error", msg)
if "calibration" in self.params and self.params["calibration"]:
import sys
sys.path.append(sys.path[0] + '/supports')
from supports import calibration
self.cal = calibration.Calibration.sharedClass
else:
self.params["calibration"] = False
self.cal = False
def setallparams(self, config):
"""
Check that 'params' used to init the object contains the required
parameters; raise an error if not. Then check whether it contains
any of the optional parameters; set them to False if not.
This is done for both the 'generic' parameters which apply to all
subclasses of this Plugin object, and for 'specific' parameters
which are defined for individual subclasses.
"""
if self.name in config.sections():
self.extractparams(config, self.requiredGenericParams, "required")
self.extractparams(config, self.requiredSpecificParams, "required")
self.extractparams(config, self.optionalGenericParams, "optional")
self.extractparams(config, self.optionalSpecificParams, "optional")
return True
else:
msg = "Missing config section for " + self.purpose + " plugin " + self.name + "."
#msg = format_msg(msg, 'error')
print(msg)
raise MissingSection
return False
def extractparams(self, config, expected, kind):
""" Extract individual parameters from a set.
Pull out individual parameters from a set (dict), and assess whether
the absence of an expected parameter is a major problem or not.
Args:
config: ConfigParser object containing the defined parameters.
expected: Dict containing the expected parameters.
kind: The kind of parameter, i.e. required or optional.
"""
if expected is not None:
extracted = {}
for param in expected:
if config.has_option(self.name, param):
extracted[param] = self.sanitiseparam(config.get(self.name, param))
else:
if kind == "required":
msg = "Missing required parameter '" + param
msg += "' for plugin " + self.name + "." + os.linesep
msg += "This should be found in the relevant .cfg file."
#msg = format_msg(msg, 'error')
print(msg)
raise MissingParameter
else:
msg = "Missing optional parameter '" + param
msg += "' for plugin " + self.name + ". Setting to False."
#msg = format_msg(msg, 'info')
#logthis(msg)
extracted[param] = False
self.params.update(extracted)
@staticmethod
def sanitiseparam(value):
""" Convert values to bool if possible.
Convert any applicable values found in a .cfg file to the appropriate
boolean, if possible. Consult the code to see exactly what is
converted.
Always test for bool first: http://www.peterbe.com/plog/bool-is-int
Args:
value: The value to be converted.
Returns:
The value as a boolean.
"""
if isinstance(value, bool):
return value
if value.lower() in ["on", "yes", "true", "1"]:
return True
if value.lower() in ["off", "no", "false", "0"]:
return False
return value
@staticmethod
def check_conn():
"""Check internet connectivity.
Check for internet connectivity by trying to connect to a website.
Returns:
boolean True if successfully connects to the site within five
seconds.
boolean False if fails to connect to the site within five
seconds.
"""
try:
urllib2.urlopen("http://www.google.com", timeout=5)
return True
except urllib2.URLError:
pass
return False
@staticmethod
def gethostname():
"""Get current hostname.
Get the current hostname of the Raspberry Pi.
Returns:
string The hostname.
"""
if socket.gethostname().find('.') >= 0:
host = socket.gethostname()
else:
host = socket.gethostbyaddr(socket.gethostname())[0]
return host
def getname(self):
"""Get Class name.
Get the name of the class. Lots of Classes inherit from this class,
so the name varies depending on which one we're looking at.
Returns:
string The class name.
"""
return self.__class__.__name__
class MissingParameter(Exception):
"""Exception to raise when the outputs.cfg file is missing a required
parameter.
"""
pass
class MissingSection(Exception):
""" Exception to raise when there is no section for the plugin in
the outputs.cfg config file.
"""
pass
class NoInternetConnection(Exception):
""" Exceeption to raise when there is no internet connectivity.
"""
pass