Skip to content

Instantly share code, notes, and snippets.

@mpapierski
Created January 31, 2019 11:00
Show Gist options
  • Save mpapierski/abf7bfcedefbf19fcb57460a0b834ac8 to your computer and use it in GitHub Desktop.
Save mpapierski/abf7bfcedefbf19fcb57460a0b834ac8 to your computer and use it in GitHub Desktop.
@contextmanager
def convert_to_pdf(filename):
"""Creates a PDF document based on input filename.
Returns a path to PDF file
"""
client = docker.from_env()
source = os.path.join('/tmp/{}'.format(os.path.basename(filename)))
expected_filename = os.path.splitext(os.path.basename(filename))[0] + '.pdf'
dest = os.path.join('/tmp/{}'.format(filename))
log.debug('Source {}'.format(source))
args = [
'--headless',
'--invisible',
'--convert-to', 'pdf:writer_pdf_Export',
'--outdir', '/tmp/',
source
]
log.info('Args {!r}'.format(args))
container = client.containers.create(
'libreoffice',
args,
tty=True)
try:
log.info('Created new container {}'.format(container.id))
# Load file inside the container using its filename through a dummy tar file
fileobj = io.BytesIO()
with tarfile.open(fileobj=fileobj, mode='w') as tar:
with open(filename, 'rb') as fin:
# Create a TarInfo object based on file object
tarinfo = tar.gettarinfo(arcname=os.path.basename(filename), fileobj=fin)
# Set chmod to 0444 so the container user can read it from /tmp
tarinfo.mode = stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH
log.info('Tarinfo {}'.format(tarinfo))
tar.addfile(tarinfo, fin)
# Upload dummy tar into /tmp/
res = container.put_archive('/tmp/', fileobj.getvalue())
# Start the container
container.start()
# Wait for the container to finish
container.wait()
# Get the logs line by line just to check how it was
for line in container.logs().decode('utf-8').splitlines():
log.info('Line {!r}'.format(line))
# Download /tmp/ contents as a tar archive
bits, archive_stat = container.get_archive('/tmp/')
log.info('Data archive {}'.format(archive_stat))
# This will extract the container
with tempfile.NamedTemporaryFile(suffix='.tar') as temp_bits:
# Download tar chunks
for chunk in bits:
temp_bits.write(chunk)
temp_bits.flush()
temp_bits.seek(0)
# Open the downloaded tar file
with tarfile.open(fileobj=temp_bits, mode='r') as tar:
for member in tar.getmembers():
log.info('List {}'.format(member))
member = tar.getmember(os.path.join('tmp', expected_filename))
log.info('Member {}'.format(member))
yield tar.extractfile(member)
finally:
log.info('Remove container {}'.format(container.id))
container.remove()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment