Skip to content

Commit

Permalink
Handle partial recordings
Browse files Browse the repository at this point in the history
This patch handles the failure of recordings, by introducing a new state for
partial recordings.

Old partial recordings are kept and moved out of the way.
The process is stopped after recording and marked as a partial recording, so
that disaster recovery can take over.

Closes #137
  • Loading branch information
shaardie authored and lkiesow committed Jun 13, 2020
1 parent 55ad188 commit cd5705b
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 9 deletions.
2 changes: 1 addition & 1 deletion etc/pyca.conf
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ directory = './recordings'
# Default: ffmpeg -nostats -re -f lavfi -r 25 -i testsrc -t {{time}} {{dir}}/{{name}}.webm'
command = 'ffmpeg -nostats -re -f lavfi -r 25 -i testsrc -f lavfi -i sine -t {{time}} {{dir}}/{{name}}.webm'

# Flavors of putput files produced by the capture command. One flavors should
# Flavors of output files produced by the capture command. One flavors should
# be specified for every output file.
# Type: list of strings (write as '...', '...')
# Default: 'presenter/source'
Expand Down
39 changes: 31 additions & 8 deletions pyca/capture.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from pyca.config import config
from pyca.db import get_session, RecordedEvent, UpcomingEvent, Status,\
Service, ServiceStatus
import glob
import logging
import os
import os.path
Expand Down Expand Up @@ -56,20 +57,25 @@ def start_capture(upcoming_event):
db.commit()

try_mkdir(config()['capture']['directory'])
os.mkdir(event.directory())
try_mkdir(event.directory())

# Set state
update_event_status(event, Status.RECORDING)
recording_state(event.uid, 'capturing')
set_service_status_immediate(Service.CAPTURE, ServiceStatus.BUSY)

# Recording
tracks = recording_command(event)
event.set_tracks(tracks)
files = recording_command(event)
# [(flavor,path),…]
event.set_tracks(list(zip(config('capture')['flavors'], files)))
db.commit()

# Set status
update_event_status(event, Status.FINISHED_RECORDING)
# If part files exist, its an partial recording
p = any([glob.glob(f'{f}-part-*') for f in files])
state = Status.PARTIAL_RECORDING if p else Status.FINISHED_RECORDING
logger.info("Set %s to %s", event.uid, Status.str(state))
update_event_status(event, state)
recording_state(event.uid, 'capture_finished')
set_service_status_immediate(Service.CAPTURE, ServiceStatus.IDLE)

Expand Down Expand Up @@ -102,6 +108,25 @@ def recording_command(event):
cmd = cmd.replace('{{name}}', event.name())
cmd = cmd.replace('{{previewdir}}', conf['preview_dir'])

# Parse files into list
files = (f.replace('{{dir}}', event.directory()) for f in conf['files'])
files = [f.replace('{{name}}', event.name()) for f in files]

# Move existing files from previous failed recordings
for f in files:
if not os.path.exists(f):
continue
# New filename
i = 0
while True:
new_filename = f'{f}-part-{i}'
if not os.path.exists(new_filename):
break
i += 1
# Move file
os.rename(f, new_filename)
logger.warning("Moved file %s to %s to keep it", f, new_filename)

# Signal configuration
sigterm_time = conf['sigterm_time']
sigkill_time = conf['sigkill_time']
Expand Down Expand Up @@ -153,10 +178,8 @@ def recording_command(event):
# Reset systemd status
notify.notify('STATUS=Waiting')

# Return [(flavor,path),…]
files = (f.replace('{{dir}}', event.directory()) for f in conf['files'])
files = (f.replace('{{name}}', event.name()) for f in files)
return list(zip(conf['flavors'], files))
# files
return files


def control_loop():
Expand Down
1 change: 1 addition & 0 deletions pyca/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ class Status(Constants):
UPLOADING = 5
FAILED_UPLOADING = 6
FINISHED_UPLOADING = 7
PARTIAL_RECORDING = 8


class ServiceStatus(Constants):
Expand Down

0 comments on commit cd5705b

Please sign in to comment.