2019-05-05 17:59:03 +00:00
|
|
|
import os
|
|
|
|
|
2019-05-04 14:56:23 +00:00
|
|
|
class Property(object):
|
|
|
|
def __init__(self, value = None):
|
|
|
|
self.value = value
|
2019-05-05 13:51:33 +00:00
|
|
|
self.callbacks = []
|
2019-05-04 14:56:23 +00:00
|
|
|
def getValue(self):
|
|
|
|
return self.value
|
|
|
|
def setValue(self, value):
|
2019-05-10 16:30:53 +00:00
|
|
|
if (self.value == value):
|
|
|
|
return self
|
2019-05-04 14:56:23 +00:00
|
|
|
self.value = value
|
2019-05-05 13:51:33 +00:00
|
|
|
for c in self.callbacks:
|
2019-05-07 16:47:03 +00:00
|
|
|
try:
|
|
|
|
c(self.value)
|
|
|
|
except Exception as e:
|
|
|
|
print(e)
|
2019-05-05 13:51:33 +00:00
|
|
|
return self
|
|
|
|
def wire(self, callback):
|
|
|
|
self.callbacks.append(callback)
|
|
|
|
if not self.value is None: callback(self.value)
|
|
|
|
return self
|
2019-05-04 14:56:23 +00:00
|
|
|
|
|
|
|
class PropertyManager(object):
|
|
|
|
sharedInstance = None
|
|
|
|
@staticmethod
|
|
|
|
def getSharedInstance():
|
|
|
|
if PropertyManager.sharedInstance is None:
|
|
|
|
PropertyManager.sharedInstance = PropertyManager()
|
|
|
|
return PropertyManager.sharedInstance
|
|
|
|
|
2019-05-07 14:32:53 +00:00
|
|
|
def collect(self, *props):
|
2019-05-09 20:44:29 +00:00
|
|
|
return PropertyManager(dict((name, self.getProperty(name) if self.hasProperty(name) else Property()) for name in props))
|
2019-05-07 14:32:53 +00:00
|
|
|
|
|
|
|
def __init__(self, properties = None):
|
2019-05-04 14:56:23 +00:00
|
|
|
self.properties = {}
|
2019-05-07 15:09:29 +00:00
|
|
|
self.callbacks = []
|
2019-05-07 14:32:53 +00:00
|
|
|
if properties is not None:
|
|
|
|
for (name, prop) in properties.items():
|
|
|
|
self.add(name, prop)
|
|
|
|
|
|
|
|
def add(self, name, prop):
|
|
|
|
self.properties[name] = prop
|
2019-05-07 15:09:29 +00:00
|
|
|
def fireCallbacks(value):
|
|
|
|
for c in self.callbacks:
|
2019-05-07 16:47:03 +00:00
|
|
|
try:
|
|
|
|
c(name, value)
|
|
|
|
except Exception as e:
|
|
|
|
print(e)
|
2019-05-07 15:09:29 +00:00
|
|
|
prop.wire(fireCallbacks)
|
|
|
|
return self
|
2019-05-07 14:32:53 +00:00
|
|
|
|
|
|
|
def __getitem__(self, name):
|
|
|
|
return self.getPropertyValue(name)
|
|
|
|
|
|
|
|
def __setitem__(self, name, value):
|
2019-05-09 20:44:29 +00:00
|
|
|
if not self.hasProperty(name):
|
|
|
|
self.add(name, Property())
|
2019-05-07 14:32:53 +00:00
|
|
|
self.getProperty(name).setValue(value)
|
2019-05-04 14:56:23 +00:00
|
|
|
|
2019-05-09 20:44:29 +00:00
|
|
|
def hasProperty(self, name):
|
|
|
|
return name in self.properties
|
|
|
|
|
2019-05-04 14:56:23 +00:00
|
|
|
def getProperty(self, name):
|
2019-05-09 20:44:29 +00:00
|
|
|
if not self.hasProperty(name):
|
2019-05-07 14:32:53 +00:00
|
|
|
self.add(name, Property())
|
2019-05-04 14:56:23 +00:00
|
|
|
return self.properties[name]
|
2019-05-04 18:26:11 +00:00
|
|
|
|
|
|
|
def getPropertyValue(self, name):
|
|
|
|
return self.getProperty(name).getValue()
|
2019-05-05 17:59:03 +00:00
|
|
|
|
2019-05-07 15:09:29 +00:00
|
|
|
def wire(self, callback):
|
|
|
|
self.callbacks.append(callback)
|
|
|
|
return self
|
|
|
|
|
2019-05-09 20:44:29 +00:00
|
|
|
def unwire(self, callback):
|
|
|
|
self.callbacks.remove(callback)
|
|
|
|
return self
|
|
|
|
|
|
|
|
def defaults(self, other_pm):
|
|
|
|
for (key, p) in self.properties.items():
|
|
|
|
if p.getValue() is None:
|
|
|
|
p.setValue(other_pm[key])
|
|
|
|
return self
|
|
|
|
|
2019-05-10 12:23:54 +00:00
|
|
|
class UnknownFeatureException(Exception):
|
|
|
|
pass
|
|
|
|
|
2019-05-05 17:59:03 +00:00
|
|
|
class RequirementMissingException(Exception):
|
|
|
|
pass
|
|
|
|
|
|
|
|
class FeatureDetector(object):
|
2019-05-07 13:50:20 +00:00
|
|
|
features = {
|
|
|
|
"core": [ "csdr", "nmux" ],
|
|
|
|
"rtl_sdr": [ "rtl_sdr" ],
|
|
|
|
"sdrplay": [ "rx_tools" ],
|
2019-05-07 15:09:29 +00:00
|
|
|
"hackrf": [ "hackrf_transfer" ]
|
2019-05-07 13:50:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
def is_available(self, feature):
|
|
|
|
return self.has_requirements(self.get_requirements(feature))
|
|
|
|
|
|
|
|
def get_requirements(self, feature):
|
2019-05-10 12:23:54 +00:00
|
|
|
try:
|
|
|
|
return FeatureDetector.features[feature]
|
|
|
|
except KeyError:
|
|
|
|
raise UnknownFeatureException("Feature \"{0}\" is not known.".format(feature))
|
2019-05-07 13:50:20 +00:00
|
|
|
|
|
|
|
def has_requirements(self, requirements):
|
|
|
|
passed = True
|
|
|
|
for requirement in requirements:
|
|
|
|
methodname = "has_" + requirement
|
|
|
|
if hasattr(self, methodname) and callable(getattr(self, methodname)):
|
|
|
|
passed = passed and getattr(self, methodname)()
|
|
|
|
else:
|
|
|
|
print("detection of requirement {0} not implement. please fix in code!".format(requirement))
|
|
|
|
return passed
|
|
|
|
|
|
|
|
def has_csdr(self):
|
|
|
|
return os.system("csdr 2> /dev/null") != 32512
|
|
|
|
|
|
|
|
def has_nmux(self):
|
|
|
|
return os.system("nmux --help 2> /dev/null") != 32512
|
|
|
|
|
|
|
|
def has_rtl_sdr(self):
|
|
|
|
return os.system("rtl_sdr --help 2> /dev/null") != 32512
|
|
|
|
|
|
|
|
def has_rx_tools(self):
|
|
|
|
return os.system("rx_sdr --help 2> /dev/null") != 32512
|
2019-05-07 15:09:29 +00:00
|
|
|
|
|
|
|
def has_hackrf_transfer(self):
|
|
|
|
# TODO i don't have a hackrf, so somebody doublecheck this.
|
|
|
|
# TODO also check if it has the stdout feature
|
|
|
|
return os.system("hackrf_transfer --help 2> /dev/null") != 32512
|