From 89ca7c10708aa54a144a592f40cb9284c3068d17 Mon Sep 17 00:00:00 2001 From: futa-ikeda Date: Thu, 5 Jun 2025 18:31:09 -0400 Subject: [PATCH 01/11] Match existing requirements to pinned WB versions --- requirements.txt | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/requirements.txt b/requirements.txt index 5a8a51a9..79a26bd7 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,7 @@ aiohttp==3.10.5 chardet==5.2.0 furl==2.0.0 -humanfriendly==10 +humanfriendly==10.0 invoke==2.2.0 mako==1.3.2 sentry-sdk==2.22.0 @@ -56,8 +56,4 @@ markdown==3.8.0 certifi==2025.1.31 - markupsafe==2.0.1 - -# Standard library imghdr redistribution because it is not supported in python 3.13. -standard-imghdr==3.13.0 From f8102ad467a17f7138eab4855b3413d31ce02b55 Mon Sep 17 00:00:00 2001 From: futa-ikeda Date: Thu, 5 Jun 2025 18:58:34 -0400 Subject: [PATCH 02/11] Remove imghdr related test failures --- mfr/extensions/image/export.py | 10 ++++++++-- mfr/extensions/pdf/export.py | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/mfr/extensions/image/export.py b/mfr/extensions/image/export.py index db4ff60f..7321889e 100644 --- a/mfr/extensions/image/export.py +++ b/mfr/extensions/image/export.py @@ -1,5 +1,4 @@ import os -import imghdr import warnings from PIL import Image @@ -72,7 +71,14 @@ def export(self): 'Unable to export the file as a {}, please check that the ' 'file is a valid image.'.format(image_type), export_format=image_type, - detected_format=imghdr.what(self.source_file_path), + detected_format= self.detect_image_format(), original_exception=err, code=400, ) + + def detect_image_format(self): + try: + with Image.open(self.source_file_path) as img: + return img.format.lower() + except Exception: + return None diff --git a/mfr/extensions/pdf/export.py b/mfr/extensions/pdf/export.py index 878cb5e6..ff69b44a 100644 --- a/mfr/extensions/pdf/export.py +++ b/mfr/extensions/pdf/export.py @@ -1,5 +1,4 @@ import os -import imghdr import logging from http import HTTPStatus @@ -94,7 +93,14 @@ def export(self): 'Unable to export the file as a {}, please check that the ' 'file is a valid tiff image.'.format(export_type), export_format=export_type, - detected_format=imghdr.what(self.source_file_path), + detected_format= self.detect_image_format(), original_exception=err, code=HTTPStatus.BAD_REQUEST, ) + + def detect_image_format(self): + try: + with Image.open(self.source_file_path) as img: + return img.format.lower() + except Exception as e: + return None From cafc90931c3b6f5e6fe9424861728ffa353f25f9 Mon Sep 17 00:00:00 2001 From: futa-ikeda Date: Thu, 5 Jun 2025 18:59:10 -0400 Subject: [PATCH 03/11] Update image related dependencies --- requirements.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 79a26bd7..412d6d82 100644 --- a/requirements.txt +++ b/requirements.txt @@ -23,8 +23,8 @@ Pygments==2.19.1 pydocx==0.9.10 # Image -olefile==0.44 -Pillow==11.0.0 +olefile==0.47 +Pillow==11.2.1 psd-tools==1.10.7 # IPython From 851fa805a10b3e66995e62a6cefb9c86c926f189 Mon Sep 17 00:00:00 2001 From: futa-ikeda Date: Mon, 9 Jun 2025 18:09:51 -0400 Subject: [PATCH 04/11] Update ipython dep group --- requirements.txt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/requirements.txt b/requirements.txt index 412d6d82..ca05376f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -29,12 +29,12 @@ psd-tools==1.10.7 # IPython ipython==7.31.1 -nbconvert==6.4.0 -nbformat==5.1.3 -traitlets==5.0 -jsonschema==2.4.0 -jinja2==3.0.0 -mistune==0.8.1 +nbconvert==7.16.6 +nbformat==5.10.4 +traitlets==5.14.3 +jsonschema==4.24.0 +jinja2==3.1.5 +mistune==3.1.2 # Pdf reportlab==4.4.0 From 211c03aa362f2948ed7c207fc4b18b0fb8a150ca Mon Sep 17 00:00:00 2001 From: futa-ikeda Date: Mon, 9 Jun 2025 18:16:48 -0400 Subject: [PATCH 05/11] Deprecation updates --- mfr/extensions/image/export.py | 4 ++-- mfr/extensions/md/render.py | 2 +- mfr/extensions/pdf/export.py | 2 +- mfr/extensions/tabular/libs/h5py_scipy_tools.py | 2 +- mfr/extensions/tabular/libs/panda_tools.py | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/mfr/extensions/image/export.py b/mfr/extensions/image/export.py index 7321889e..a86ca43d 100644 --- a/mfr/extensions/image/export.py +++ b/mfr/extensions/image/export.py @@ -13,7 +13,7 @@ class ImageExporter(extension.BaseExporter): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.metrics.add('pil_version', Image.VERSION) + self.metrics.add('pil_version', Image.__version__) def export(self): parts = self.format.split('.') @@ -44,7 +44,7 @@ def export(self): self.metrics.add('ratio', ratio) if ratio < 1: size_tuple = (round(image.size[0] * ratio), round(image.size[1] * ratio)) - image = image.resize(size_tuple, Image.ANTIALIAS) + image = image.resize(size_tuple, Image.Resampling.LANCZOS) # Mode 'P' is for paletted images. They must be converted to RGB before exporting to # jpeg, otherwise Pillow will throw an error. This is a temporary workaround, as the diff --git a/mfr/extensions/md/render.py b/mfr/extensions/md/render.py index 45027cf1..e6b1388e 100644 --- a/mfr/extensions/md/render.py +++ b/mfr/extensions/md/render.py @@ -24,7 +24,7 @@ class MdRenderer(extension.BaseRenderer): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.metrics.add('markdown_version', markdown.version) + self.metrics.add('markdown_version', markdown.__version__) def render(self): """Render a markdown file to html.""" diff --git a/mfr/extensions/pdf/export.py b/mfr/extensions/pdf/export.py index ff69b44a..b9193568 100644 --- a/mfr/extensions/pdf/export.py +++ b/mfr/extensions/pdf/export.py @@ -17,7 +17,7 @@ class PdfExporter(extension.BaseExporter): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) - self.metrics.add('pil_version', Image.VERSION) + self.metrics.add('pil_version', Image.__version__) def tiff_to_pdf(self, tiff_img, max_size): """ Turn a tiff into a pdf to support multipage tiffs""" diff --git a/mfr/extensions/tabular/libs/h5py_scipy_tools.py b/mfr/extensions/tabular/libs/h5py_scipy_tools.py index 4e6bcf4c..1090d038 100644 --- a/mfr/extensions/tabular/libs/h5py_scipy_tools.py +++ b/mfr/extensions/tabular/libs/h5py_scipy_tools.py @@ -31,7 +31,7 @@ def mat_v73(fp): if isinstance(data, h5py.Dataset): # h5py Uses row-major ordering. this fixes it so it displays like it does in matlab # basically just flip it on its axis - list_data = list(zip(*data.value.tolist())) + list_data = list(zip(*data[()].tolist())) build_sheets(name, list_data, sheets) return sheets diff --git a/mfr/extensions/tabular/libs/panda_tools.py b/mfr/extensions/tabular/libs/panda_tools.py index 14918a4b..0f489185 100644 --- a/mfr/extensions/tabular/libs/panda_tools.py +++ b/mfr/extensions/tabular/libs/panda_tools.py @@ -62,7 +62,7 @@ def data_from_dataframe(dataframe): data = [] for _, frame_row in dataframe.iterrows(): data_row = {} - for name, value in frame_row.iteritems(): + for name, value in frame_row.items(): try: data_row[name] = numpy.asscalar(value) except AttributeError: From c0925a9f17193b4fc4bd6ee4d3db71c9e76500c9 Mon Sep 17 00:00:00 2001 From: futa-ikeda Date: Mon, 9 Jun 2025 18:18:48 -0400 Subject: [PATCH 06/11] Update tests to not call fixtures directly --- tests/extensions/audio/test_renderer.py | 4 ++-- tests/extensions/codepygments/test_renderer.py | 4 ++-- tests/extensions/docx/test_renderer.py | 4 ++-- tests/extensions/ipynb/test_renderer.py | 4 ++-- tests/extensions/jamovi/test_renderer.py | 4 ++-- tests/extensions/jasp/test_renderer.py | 6 +++--- tests/extensions/jsc3d/test_renderer.py | 4 ++-- tests/extensions/md/test_renderer.py | 6 +++--- tests/extensions/pdb/test_renderer.py | 4 ++-- tests/extensions/rst/test_renderer.py | 4 ++-- tests/extensions/tabular/test_renderer.py | 4 ++-- tests/extensions/video/test_renderer.py | 8 ++++---- 12 files changed, 28 insertions(+), 28 deletions(-) diff --git a/tests/extensions/audio/test_renderer.py b/tests/extensions/audio/test_renderer.py index 4fa7a465..50712fe7 100644 --- a/tests/extensions/audio/test_renderer.py +++ b/tests/extensions/audio/test_renderer.py @@ -26,8 +26,8 @@ def assets_url(): @pytest.fixture -def export_url(): - return 'http://mfr.osf.io/export?url=' + url() +def export_url(url): + return 'http://mfr.osf.io/export?url=' + url @pytest.fixture diff --git a/tests/extensions/codepygments/test_renderer.py b/tests/extensions/codepygments/test_renderer.py index 31034adf..6b9e26a1 100644 --- a/tests/extensions/codepygments/test_renderer.py +++ b/tests/extensions/codepygments/test_renderer.py @@ -58,8 +58,8 @@ def assets_url(): @pytest.fixture -def export_url(): - return 'http://mfr.osf.io/export?url=' + url() +def export_url(url): + return 'http://mfr.osf.io/export?url=' + url @pytest.fixture diff --git a/tests/extensions/docx/test_renderer.py b/tests/extensions/docx/test_renderer.py index 9d26c036..fbcee005 100644 --- a/tests/extensions/docx/test_renderer.py +++ b/tests/extensions/docx/test_renderer.py @@ -39,8 +39,8 @@ def renderer(metadata, test_file_path, url, assets_url, export_url): @pytest.fixture -def export_url(): - return 'http://mfr.osf.io/export?url=' + url() +def export_url(url): + return 'http://mfr.osf.io/export?url=' + url diff --git a/tests/extensions/ipynb/test_renderer.py b/tests/extensions/ipynb/test_renderer.py index 34ed4e36..88dbea7a 100644 --- a/tests/extensions/ipynb/test_renderer.py +++ b/tests/extensions/ipynb/test_renderer.py @@ -38,8 +38,8 @@ def assets_url(): @pytest.fixture -def export_url(): - return 'http://mfr.osf.io/export?url=' + url() +def export_url(url): + return 'http://mfr.osf.io/export?url=' + url @pytest.fixture diff --git a/tests/extensions/jamovi/test_renderer.py b/tests/extensions/jamovi/test_renderer.py index f6f6bffd..ab66017e 100644 --- a/tests/extensions/jamovi/test_renderer.py +++ b/tests/extensions/jamovi/test_renderer.py @@ -59,8 +59,8 @@ def assets_url(): return 'http://mfr.osf.io/assets' @pytest.fixture -def export_url(): - return 'http://mfr.osf.io/export?url=' + url() +def export_url(url): + return 'http://mfr.osf.io/export?url=' + url @pytest.fixture def extension(): diff --git a/tests/extensions/jasp/test_renderer.py b/tests/extensions/jasp/test_renderer.py index 0dc91bab..fe97829c 100644 --- a/tests/extensions/jasp/test_renderer.py +++ b/tests/extensions/jasp/test_renderer.py @@ -53,8 +53,8 @@ def assets_url(): @pytest.fixture -def export_url(): - return 'http://mfr.osf.io/export?url=' + url() +def export_url(url): + return 'http://mfr.osf.io/export?url=' + url @pytest.fixture @@ -128,7 +128,7 @@ def test_render_JASP_contains_malicious_script(self, metadata, contains_maliciou body = renderer.render() assert ' - diff --git a/requirements.txt b/requirements.txt index 0f517405..06284194 100644 --- a/requirements.txt +++ b/requirements.txt @@ -20,7 +20,6 @@ Pygments==2.19.1 # Docx #git+https://github.com/jsocol/bleach.git -pydocx==0.9.10 # Image olefile==0.47 diff --git a/tests/extensions/docx/__init__.py b/tests/extensions/docx/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/extensions/docx/files/invalid.docx b/tests/extensions/docx/files/invalid.docx deleted file mode 100644 index 9db8f3c1..00000000 --- a/tests/extensions/docx/files/invalid.docx +++ /dev/null @@ -1,134 +0,0 @@ - -pg_dump -createdb -- create a new PostgreSQL database -Installing ----------- - -requires: - -:: - - sudo pip install appscript GitPython gitconfig gitinfo - -macos.notify() on Mac OS < 10.8 requires `Growl <http://growl.info/>`_ - -macos.temperature requires `Temperature -Monitor <http://www.bresink.com/osx/TemperatureMonitor.html>`_ - -macos.app.ical.today\_events() requires -`icalBuddy <http://hasseg.org/icalBuddy/>`_ - -macos.display.sleep() requires `Sleep -Display <http://www.malcolmhall.com/products/sleepdisplay/>`_ - -:: - - sudo pip install macos - - Usage ---------- - -:: - - import macos - print macos.version - print macos.shell("ls /") - print macos.shell("sudo python setup.py install",True) # osascript -e "do shell script %s with administrator privileges" - if macos.idle()>10: - macos.purge() # run purge command (optimize RAM) - if macos.idle()>5*60: - macos.display.sleep() # turn off display - - - # volume, say - macos.volume.muted=False - macos.volume.alert, macos.volume.input, macos.volume.output =(0,14,88) - print "volume [input=%s,output=%s,alert=%s]" % (macos.volume.input, macos.volume.output, macos.volume.alert) - macos.say("We must secure the existence of our people and a future for White Children",using="Alex") - - # AppleScript - macos.osascript('tell application "iTunes" to play') - - - # launchctl - print macos.launchctl.running("myagent") - for l in macos.launchctl.list() - print l.pid, l.exitstatus, l.label - - # notify - from macos import notify - notify("title","desc") - notify("title","desc",app="iCal",sticky=True) - - # iCal - from macos.app import ical - if ical.running: - for todo in ical.todos: - if todo.completion_date: - print todo.uid,todo.summary,"completed" - todo.delete() - ical.todo("new todo","description") # add new todo - for e in in ical.events: - print e.uid,e.summary,e.description - get_event("summary").start_date=datetime.now() - - # iTunes - from macos.app import itunes - print itunes.running, itunes.playing - itunes.pause(), itunes.play(), itunes.stop() - itunes.fadein(5), itunes.fadeout(5) - - # Skype - from macos.app import skype - print skype.running,skype.calling - - # VLC - from macos.app import vlc - print vlc.running, vlc.playing - vlc.open("~/press.avi").fullscreen().volume(100) - - # Transmission - from macos.app import transmission - transmission.open() - transmission.close() - - # Chrome - from macos.app import chrome - if chrome.running: - for t in chrome.tabs: - print t.url,t.title - t.reload() - macos.open("http://127.0.0.1") - - for a in macos.user.library.launchagents: - print l.pid, l.exitstatus, l.label - - for a in macos.user.library.launchagents: # plistlib objects - print a.Label, macos.launchctl.running(a.Label) - - # git - print macos.user.gitconfig.user.name, macos.user.gitconfig.github.password - print macos.user.git.path, macos.user.git.exists # ~/git - for dir in macos.user.git: # iterate repositories dirs - print "" - print dir.path,dir.git - if dir.git: - print dir.repo # dir.repo is GitPython Repo object - # Shorthands: - print dir.nothing_to_commit - print dir.status - print "modified=",dir.modified - print "deleted=",dir.deleted - print "untracked=",dir.untracked - - # temperature - print macos.temperature.air - -TODO - -- Terminal -- Firefox - -cancerhermit -b9b695d3ed85f6f39fccffc186a71a2f21dfa096 -0.0.1 - \ No newline at end of file diff --git a/tests/extensions/docx/files/test.docx b/tests/extensions/docx/files/test.docx deleted file mode 100644 index f6b3d6a71555918a2b098d6a3afc1c60b4f54cda..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5003 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' in body - - def test_render_docx_invalid(self, metadata, invalid_file_path, url, assets_url, export_url): - renderer = DocxRenderer(metadata, invalid_file_path, url, assets_url, export_url) - with pytest.raises(MalformedDocxException): - renderer.render() - - def test_render_docx_file_required(self, renderer): - assert renderer.file_required is True - - def test_render_docx_cache_result(self, renderer): - assert renderer.cache_result is True