forked from rc/aircox
tests: playlist_import, log_archiver, sound_stats.SoxStats
This commit is contained in:
@ -42,6 +42,7 @@ class LogArchiver:
|
||||
# exists yet <3
|
||||
for (station, date), logs in logs.items():
|
||||
path = self.get_path(station, date)
|
||||
# FIXME: remove binary mode
|
||||
with gzip.open(path, "ab") as archive:
|
||||
data = yaml.dump(
|
||||
[self.serialize(line) for line in logs]
|
||||
@ -60,11 +61,8 @@ class LogArchiver:
|
||||
qs = qs.order_by("date")
|
||||
logs = {}
|
||||
for log in qs:
|
||||
key = (log.station, log.date)
|
||||
if key not in logs:
|
||||
logs[key] = [log]
|
||||
else:
|
||||
logs[key].append(log)
|
||||
key = (log.station, log.date.date())
|
||||
logs.setdefault(key, []).append(log)
|
||||
return logs
|
||||
|
||||
def serialize(self, log):
|
||||
@ -73,13 +71,13 @@ class LogArchiver:
|
||||
|
||||
def load(self, station, date):
|
||||
"""Load an archive returning logs in a list."""
|
||||
from aircox.models import Log
|
||||
|
||||
path = self.get_path(station, date)
|
||||
|
||||
if not os.path.exists(path):
|
||||
return []
|
||||
return self.load_file(path)
|
||||
|
||||
def load_file(self, path):
|
||||
with gzip.open(path, "rb") as archive:
|
||||
data = archive.read()
|
||||
logs = yaml.load(data)
|
||||
@ -110,5 +108,5 @@ class LogArchiver:
|
||||
"""From a list of dict representing logs, retrieve related objects of
|
||||
the given type."""
|
||||
attr_id = attr + "_id"
|
||||
pks = (log[attr_id] for log in logs if attr_id in log)
|
||||
pks = {log[attr_id] for log in logs if attr_id in log}
|
||||
return {rel.pk: rel for rel in model.objects.filter(pk__in=pks)}
|
||||
|
@ -24,16 +24,30 @@ class SoxStats:
|
||||
"Length s",
|
||||
]
|
||||
|
||||
def __init__(self, path, **kwargs):
|
||||
values = None
|
||||
|
||||
def __init__(self, path=None, **kwargs):
|
||||
"""If path is given, call analyse with path and kwargs."""
|
||||
self.values = {}
|
||||
if path:
|
||||
self.analyse(path, **kwargs)
|
||||
|
||||
def get(self, attr):
|
||||
return self.values.get(attr)
|
||||
def analyse(self, path, at=None, length=None):
|
||||
"""If at and length are given use them as excerpt to analyse."""
|
||||
args = ["sox", path, "-n"]
|
||||
if at is not None and length is not None:
|
||||
args += ["trim", str(at), str(length)]
|
||||
args.append("stats")
|
||||
|
||||
p = subprocess.Popen(
|
||||
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
# sox outputs to stderr (my god WHYYYY)
|
||||
out_, out = p.communicate()
|
||||
self.values = self.parse(str(out, encoding="utf-8"))
|
||||
|
||||
def parse(self, output):
|
||||
"""Parse sox output, settubg values from it."""
|
||||
values = {}
|
||||
for attr in self.attributes:
|
||||
value = re.search(attr + r"\s+(?P<value>\S+)", output)
|
||||
value = value and value.groupdict()
|
||||
@ -42,24 +56,12 @@ class SoxStats:
|
||||
value = float(value.get("value"))
|
||||
except ValueError:
|
||||
value = None
|
||||
self.values[attr] = value
|
||||
self.values["length"] = self.values["Length s"]
|
||||
values[attr] = value
|
||||
values["length"] = values.pop("Length s", None)
|
||||
return values
|
||||
|
||||
def analyse(self, path, at=None, length=None):
|
||||
"""If at and length are given use them as excerpt to analyse."""
|
||||
args = ["sox", path, "-n"]
|
||||
|
||||
if at is not None and length is not None:
|
||||
args += ["trim", str(at), str(length)]
|
||||
|
||||
args.append("stats")
|
||||
|
||||
p = subprocess.Popen(
|
||||
args, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
# sox outputs to stderr (my god WHYYYY)
|
||||
out_, out = p.communicate()
|
||||
self.parse(str(out, encoding="utf-8"))
|
||||
def get(self, attr):
|
||||
return self.values.get(attr)
|
||||
|
||||
|
||||
class SoundStats:
|
||||
|
Reference in New Issue
Block a user