Skip to content

[SVCS-86] Add Papaya Renderer for Dicom and NifTi Files #265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions mfr/core/utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
from time import time
from os.path import getctime

from stevedore import driver

from mfr.core import exceptions
from mfr.extensions import settings as ext_settings


def make_provider(name, request, url):
Expand Down Expand Up @@ -97,6 +101,7 @@ def make_renderer(name, metadata, file_path, url, assets_url, export_url):
}
)


def sizeof_fmt(num, suffix='B'):
if abs(num) < 1000:
return '%3.0f%s' % (num, suffix)
Expand All @@ -106,3 +111,33 @@ def sizeof_fmt(num, suffix='B'):
return '%3.1f%s%s' % (num, unit, suffix)
num /= 1000.0
return '%.1f%s%s' % (num, 'Y', suffix)


def file_expired(path: str, ttl: int) -> bool:
"""Helper method that checks if a file's last change time has expired ttl.

:param path: the path of the file
:param ttl: the expiration time in seconds
:return: True if expired, False otherwise
"""

if (time() - getctime(path)) >= ttl:
return True
return False


def get_full_file_ext(file_ext: str, file_name: str) -> str:
"""Helper method that checks if a secondary extension exists for a file
with a compressed extension as primary. If so, returns the full extension.

:param metadata_ext: the file's primary extension
:param metadata_name: the file name that may contain a secondary extension
:return: the file's full extension
"""

compressed_ext = ext_settings.COMPRESSED_EXT
if file_ext in compressed_ext.keys():
secondary_ext = '.{}'.format(file_name.split('.')[-1])
if secondary_ext in compressed_ext[file_ext]:
return secondary_ext + file_ext
return file_ext
1 change: 1 addition & 0 deletions mfr/extensions/papaya/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .render import PapayaRenderer # noqa
43 changes: 43 additions & 0 deletions mfr/extensions/papaya/render.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import os
import shutil

from mako.lookup import TemplateLookup

from mfr.core import utils
from mfr.core import extension
from mfr.extensions import settings as ext_settings
from mfr.extensions.papaya import settings as papaya_settings


class PapayaRenderer(extension.BaseRenderer):

data_dir = papaya_settings.DATA_DIR
data_ttl = papaya_settings.DATA_TTL
comp_ext = ext_settings.COMPRESSED_EXT

TEMPLATE = TemplateLookup(
directories=[
os.path.join(os.path.dirname(__file__), 'templates')
]).get_template('viewer.mako')

def render(self):
self.remove_old_files()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean the temporary files for rendering will get stuck here all the time? Each time users try to render a file, the old ones gets removed but new ones are created.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is correct.

Copy link
Contributor

@cslzchen cslzchen Nov 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure how much this will impact prod memory. MFR and WB pods constantly run out of space though. I will leave this for Phase 2 Review.

file_name = os.path.basename(self.file_path)
file_ext = utils.get_full_file_ext(self.metadata.ext, self.metadata.name)
file_name = file_name + file_ext
shutil.copyfile(self.file_path, self.data_dir + file_name)
return self.TEMPLATE.render(base=self.assets_url, file_name=file_name)

def remove_old_files(self):

for data_file in os.listdir(self.data_dir):
if utils.file_expired(self.data_dir + data_file, self.data_ttl):
os.unlink(self.data_dir + data_file)

@property
def file_required(self):
return True

@property
def cache_result(self):
return True
8 changes: 8 additions & 0 deletions mfr/extensions/papaya/settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from mfr import settings

config = settings.child('PAPAYA_EXTENSION_CONFIG')

# Directory to temporarily store papaya image files
DATA_DIR = 'mfr/extensions/papaya/static/data/'
# Files older then this many seconds will be deleted from DATA_DIR at the beginning of each render.
DATA_TTL = 300
7 changes: 7 additions & 0 deletions mfr/extensions/papaya/static/README-papaya.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Currently using a custom built papaya.js with option to remove the ability to open new files from the users desktop.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO: Remove this file. PR was accepted and we are no longer using custom build.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 Nicely done!


https://github.com/TomBaxter/Papaya/tree/feature/noNewFiles

I have sent them a PR, hopefully they bite.

https://github.com/rii-mango/Papaya/pull/101
Empty file.
1 change: 1 addition & 0 deletions mfr/extensions/papaya/static/papaya.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading