napari-timestamper 0.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. napari-timestamper-0.0.1/.github/workflows/test_and_deploy.yml +90 -0
  2. napari-timestamper-0.0.1/.gitignore +84 -0
  3. napari-timestamper-0.0.1/.napari-hub/DESCRIPTION.md +9 -0
  4. napari-timestamper-0.0.1/.napari-hub/config.yml +1 -0
  5. napari-timestamper-0.0.1/.pre-commit-config.yaml +21 -0
  6. napari-timestamper-0.0.1/42.0.0 +12 -0
  7. napari-timestamper-0.0.1/LICENSE +28 -0
  8. napari-timestamper-0.0.1/MANIFEST.in +5 -0
  9. napari-timestamper-0.0.1/PKG-INFO +89 -0
  10. napari-timestamper-0.0.1/README.md +60 -0
  11. napari-timestamper-0.0.1/pyproject.toml +58 -0
  12. napari-timestamper-0.0.1/setup.cfg +63 -0
  13. napari-timestamper-0.0.1/src/napari_timestamper/__init__.py +7 -0
  14. napari-timestamper-0.0.1/src/napari_timestamper/_tests/__init__.py +0 -0
  15. napari-timestamper-0.0.1/src/napari_timestamper/_tests/test_timestamp_overlay.py +15 -0
  16. napari-timestamper-0.0.1/src/napari_timestamper/_tests/test_widget.py +67 -0
  17. napari-timestamper-0.0.1/src/napari_timestamper/_timestamp_overlay.py +233 -0
  18. napari-timestamper-0.0.1/src/napari_timestamper/_version.py +4 -0
  19. napari-timestamper-0.0.1/src/napari_timestamper/_widget.py +220 -0
  20. napari-timestamper-0.0.1/src/napari_timestamper/napari.yaml +10 -0
  21. napari-timestamper-0.0.1/src/napari_timestamper.egg-info/PKG-INFO +89 -0
  22. napari-timestamper-0.0.1/src/napari_timestamper.egg-info/SOURCES.txt +26 -0
  23. napari-timestamper-0.0.1/src/napari_timestamper.egg-info/dependency_links.txt +1 -0
  24. napari-timestamper-0.0.1/src/napari_timestamper.egg-info/entry_points.txt +2 -0
  25. napari-timestamper-0.0.1/src/napari_timestamper.egg-info/requires.txt +10 -0
  26. napari-timestamper-0.0.1/src/napari_timestamper.egg-info/top_level.txt +1 -0
  27. napari-timestamper-0.0.1/tox.ini +32 -0
@@ -0,0 +1,90 @@
1
+ # This workflows will upload a Python Package using Twine when a release is created
2
+ # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries
3
+
4
+ name: tests
5
+
6
+ on:
7
+ push:
8
+ branches:
9
+ - main
10
+ - npe2
11
+ tags:
12
+ - "v*" # Push events to matching v*, i.e. v1.0, v20.15.10
13
+ pull_request:
14
+ branches:
15
+ - main
16
+ - npe2
17
+ workflow_dispatch:
18
+
19
+ jobs:
20
+ test:
21
+ name: ${{ matrix.platform }} py${{ matrix.python-version }}
22
+ runs-on: ${{ matrix.platform }}
23
+ strategy:
24
+ matrix:
25
+ platform: [ubuntu-latest, windows-latest, macos-latest]
26
+ python-version: ['3.8', '3.9', '3.10']
27
+
28
+ steps:
29
+ - uses: actions/checkout@v3
30
+
31
+ - name: Set up Python ${{ matrix.python-version }}
32
+ uses: actions/setup-python@v4
33
+ with:
34
+ python-version: ${{ matrix.python-version }}
35
+
36
+ # these libraries enable testing on Qt on linux
37
+ - uses: tlambert03/setup-qt-libs@v1
38
+
39
+ # strategy borrowed from vispy for installing opengl libs on windows
40
+ - name: Install Windows OpenGL
41
+ if: runner.os == 'Windows'
42
+ run: |
43
+ git clone --depth 1 https://github.com/pyvista/gl-ci-helpers.git
44
+ powershell gl-ci-helpers/appveyor/install_opengl.ps1
45
+
46
+ # note: if you need dependencies from conda, considering using
47
+ # setup-miniconda: https://github.com/conda-incubator/setup-miniconda
48
+ # and
49
+ # tox-conda: https://github.com/tox-dev/tox-conda
50
+ - name: Install dependencies
51
+ run: |
52
+ python -m pip install --upgrade pip
53
+ python -m pip install setuptools tox tox-gh-actions
54
+
55
+ # this runs the platform-specific tests declared in tox.ini
56
+ - name: Test with tox
57
+ uses: aganders3/headless-gui@v1
58
+ with:
59
+ run: python -m tox
60
+ env:
61
+ PLATFORM: ${{ matrix.platform }}
62
+
63
+ - name: Coverage
64
+ uses: codecov/codecov-action@v3
65
+
66
+ deploy:
67
+ # this will run when you have tagged a commit, starting with "v*"
68
+ # and requires that you have put your twine API key in your
69
+ # github secrets (see readme for details)
70
+ needs: [test]
71
+ runs-on: ubuntu-latest
72
+ if: contains(github.ref, 'tags')
73
+ steps:
74
+ - uses: actions/checkout@v3
75
+ - name: Set up Python
76
+ uses: actions/setup-python@v4
77
+ with:
78
+ python-version: "3.x"
79
+ - name: Install dependencies
80
+ run: |
81
+ python -m pip install --upgrade pip
82
+ pip install -U setuptools setuptools_scm wheel twine build
83
+ - name: Build and publish
84
+ env:
85
+ TWINE_USERNAME: __token__
86
+ TWINE_PASSWORD: ${{ secrets.TWINE_API_KEY }}
87
+ run: |
88
+ git tag
89
+ python -m build .
90
+ twine upload dist/*
@@ -0,0 +1,84 @@
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ env/
12
+ build/
13
+ develop-eggs/
14
+ dist/
15
+ downloads/
16
+ eggs/
17
+ .eggs/
18
+ lib/
19
+ lib64/
20
+ parts/
21
+ sdist/
22
+ var/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+
27
+ # PyInstaller
28
+ # Usually these files are written by a python script from a template
29
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
30
+ *.manifest
31
+ *.spec
32
+
33
+ # Installer logs
34
+ pip-log.txt
35
+ pip-delete-this-directory.txt
36
+
37
+ # Unit test / coverage reports
38
+ htmlcov/
39
+ .tox/
40
+ .coverage
41
+ .coverage.*
42
+ .cache
43
+ nosetests.xml
44
+ coverage.xml
45
+ *,cover
46
+ .hypothesis/
47
+ .napari_cache
48
+
49
+ # Translations
50
+ *.mo
51
+ *.pot
52
+
53
+ # Django stuff:
54
+ *.log
55
+ local_settings.py
56
+
57
+ # Flask instance folder
58
+ instance/
59
+
60
+ # Sphinx documentation
61
+ docs/_build/
62
+
63
+ # MkDocs documentation
64
+ /site/
65
+
66
+ # PyBuilder
67
+ target/
68
+
69
+ # Pycharm and VSCode
70
+ .idea/
71
+ venv/
72
+ .vscode/
73
+
74
+ # IPython Notebook
75
+ .ipynb_checkpoints
76
+
77
+ # pyenv
78
+ .python-version
79
+
80
+ # OS
81
+ .DS_Store
82
+
83
+ # written by setuptools_scm
84
+ **/_version.py
@@ -0,0 +1,9 @@
1
+ <!-- This file is a placeholder for customizing description of your plugin
2
+ on the napari hub if you wish. The readme file will be used by default if
3
+ you wish not to do any customization for the napari hub listing.
4
+
5
+ If you need some help writing a good description, check out our
6
+ [guide](https://github.com/chanzuckerberg/napari-hub/wiki/Writing-the-Perfect-Description-for-your-Plugin)
7
+ -->
8
+
9
+ The developer has not yet provided a napari-hub specific description.
@@ -0,0 +1 @@
1
+ visibility: disabled
@@ -0,0 +1,21 @@
1
+ repos:
2
+ - repo: https://github.com/pre-commit/pre-commit-hooks
3
+ rev: v4.4.0
4
+ hooks:
5
+ - id: check-docstring-first
6
+ - id: end-of-file-fixer
7
+ - id: trailing-whitespace
8
+ exclude: ^\.napari-hub/.*
9
+ - id: check-yaml # checks for correct yaml syntax for github actions ex.
10
+ - repo: https://github.com/charliermarsh/ruff-pre-commit
11
+ rev: v0.0.286
12
+ hooks:
13
+ - id: ruff
14
+ - repo: https://github.com/psf/black
15
+ rev: 23.7.0
16
+ hooks:
17
+ - id: black
18
+ - repo: https://github.com/tlambert03/napari-plugin-checks
19
+ rev: v0.3.0
20
+ hooks:
21
+ - id: napari-plugin-checks
@@ -0,0 +1,12 @@
1
+ Requirement already satisfied: setuptools in c:\users\benig\documents\python_dev\napari-timestamper\.tox\.package\lib\site-packages (68.1.2)
2
+ Requirement already satisfied: wheel in c:\users\benig\documents\python_dev\napari-timestamper\.tox\.package\lib\site-packages (0.41.2)
3
+ Collecting setuptools_scm
4
+ Using cached setuptools_scm-7.1.0-py3-none-any.whl (43 kB)
5
+ Collecting packaging>=20.0 (from setuptools_scm)
6
+ Using cached packaging-23.1-py3-none-any.whl (48 kB)
7
+ Collecting typing-extensions (from setuptools_scm)
8
+ Obtaining dependency information for typing-extensions from https://files.pythonhosted.org/packages/ec/6b/63cc3df74987c36fe26157ee12e09e8f9db4de771e0f3404263117e75b95/typing_extensions-4.7.1-py3-none-any.whl.metadata
9
+ Using cached typing_extensions-4.7.1-py3-none-any.whl.metadata (3.1 kB)
10
+ Using cached typing_extensions-4.7.1-py3-none-any.whl (33 kB)
11
+ Installing collected packages: typing-extensions, packaging, setuptools_scm
12
+ Successfully installed packaging-23.1 setuptools_scm-7.1.0 typing-extensions-4.7.1
@@ -0,0 +1,28 @@
1
+
2
+ Copyright (c) 2023, Benjamin Grädel
3
+ All rights reserved.
4
+
5
+ Redistribution and use in source and binary forms, with or without
6
+ modification, are permitted provided that the following conditions are met:
7
+
8
+ * Redistributions of source code must retain the above copyright notice, this
9
+ list of conditions and the following disclaimer.
10
+
11
+ * Redistributions in binary form must reproduce the above copyright notice,
12
+ this list of conditions and the following disclaimer in the documentation
13
+ and/or other materials provided with the distribution.
14
+
15
+ * Neither the name of copyright holder nor the names of its
16
+ contributors may be used to endorse or promote products derived from
17
+ this software without specific prior written permission.
18
+
19
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27
+ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
+ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,5 @@
1
+ include LICENSE
2
+ include README.md
3
+
4
+ recursive-exclude * __pycache__
5
+ recursive-exclude * *.py[co]
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.1
2
+ Name: napari-timestamper
3
+ Version: 0.0.1
4
+ Summary: A simple plugin to add a timestamp overlay to napari
5
+ Home-page: https://github.com/bgraedel/napari-timestamper
6
+ Author: Benjamin Grädel
7
+ Author-email: benjamin.graedel@unibe.ch
8
+ License: BSD-3-Clause
9
+ Project-URL: Bug Tracker, https://github.com/bgraedel/napari-timestamper/issues
10
+ Project-URL: Documentation, https://github.com/bgraedel/napari-timestamper#README.md
11
+ Project-URL: Source Code, https://github.com/bgraedel/napari-timestamper
12
+ Project-URL: User Support, https://github.com/bgraedel/napari-timestamper/issues
13
+ Classifier: Development Status :: 2 - Pre-Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: BSD License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: 3.8
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ Provides-Extra: testing
28
+ License-File: LICENSE
29
+
30
+ # napari-timestamper
31
+
32
+ [![License BSD-3](https://img.shields.io/pypi/l/napari-timestamper.svg?color=green)](https://github.com/bgraedel/napari-timestamper/raw/main/LICENSE)
33
+ [![PyPI](https://img.shields.io/pypi/v/napari-timestamper.svg?color=green)](https://pypi.org/project/napari-timestamper)
34
+ [![Python Version](https://img.shields.io/pypi/pyversions/napari-timestamper.svg?color=green)](https://python.org)
35
+ [![tests](https://github.com/bgraedel/napari-timestamper/workflows/tests/badge.svg)](https://github.com/bgraedel/napari-timestamper/actions)
36
+ [![codecov](https://codecov.io/gh/bgraedel/napari-timestamper/branch/main/graph/badge.svg)](https://codecov.io/gh/bgraedel/napari-timestamper)
37
+ <!-- [![napari hub](https://img.shields.io/endpoint?url=https://api.napari-hub.org/shields/napari-timestamper)](https://napari-hub.org/plugins/napari-timestamper) -->
38
+
39
+ A simple plugin to add a timestamp overlay to napari
40
+ uses some private overlay functionality, so may break in the future
41
+
42
+ ----------------------------------
43
+
44
+ This [napari] plugin was generated with [Cookiecutter] using [@napari]'s [cookiecutter-napari-plugin] template.
45
+
46
+ ## Installation
47
+
48
+ You can install `napari-timestamper` via [pip]: [not yet on PyPI]
49
+
50
+ pip install napari-timestamper
51
+
52
+
53
+
54
+ To install latest development version :
55
+
56
+ pip install git+https://github.com/bgraedel/napari-timestamper.git
57
+
58
+
59
+ ## Contributing
60
+
61
+ Contributions are very welcome. Tests can be run with [tox], please ensure
62
+ the coverage at least stays the same before you submit a pull request.
63
+
64
+ ## License
65
+
66
+ Distributed under the terms of the [BSD-3] license,
67
+ "napari-timestamper" is free and open source software
68
+
69
+ ## Issues
70
+
71
+ If you encounter any problems, please [file an issue] along with a detailed description.
72
+
73
+ [napari]: https://github.com/napari/napari
74
+ [Cookiecutter]: https://github.com/audreyr/cookiecutter
75
+ [@napari]: https://github.com/napari
76
+ [MIT]: http://opensource.org/licenses/MIT
77
+ [BSD-3]: http://opensource.org/licenses/BSD-3-Clause
78
+ [GNU GPL v3.0]: http://www.gnu.org/licenses/gpl-3.0.txt
79
+ [GNU LGPL v3.0]: http://www.gnu.org/licenses/lgpl-3.0.txt
80
+ [Apache Software License 2.0]: http://www.apache.org/licenses/LICENSE-2.0
81
+ [Mozilla Public License 2.0]: https://www.mozilla.org/media/MPL/2.0/index.txt
82
+ [cookiecutter-napari-plugin]: https://github.com/napari/cookiecutter-napari-plugin
83
+
84
+ [file an issue]: https://github.com/bgraedel/napari-timestamper/issues
85
+
86
+ [napari]: https://github.com/napari/napari
87
+ [tox]: https://tox.readthedocs.io/en/latest/
88
+ [pip]: https://pypi.org/project/pip/
89
+ [PyPI]: https://pypi.org/
@@ -0,0 +1,60 @@
1
+ # napari-timestamper
2
+
3
+ [![License BSD-3](https://img.shields.io/pypi/l/napari-timestamper.svg?color=green)](https://github.com/bgraedel/napari-timestamper/raw/main/LICENSE)
4
+ [![PyPI](https://img.shields.io/pypi/v/napari-timestamper.svg?color=green)](https://pypi.org/project/napari-timestamper)
5
+ [![Python Version](https://img.shields.io/pypi/pyversions/napari-timestamper.svg?color=green)](https://python.org)
6
+ [![tests](https://github.com/bgraedel/napari-timestamper/workflows/tests/badge.svg)](https://github.com/bgraedel/napari-timestamper/actions)
7
+ [![codecov](https://codecov.io/gh/bgraedel/napari-timestamper/branch/main/graph/badge.svg)](https://codecov.io/gh/bgraedel/napari-timestamper)
8
+ <!-- [![napari hub](https://img.shields.io/endpoint?url=https://api.napari-hub.org/shields/napari-timestamper)](https://napari-hub.org/plugins/napari-timestamper) -->
9
+
10
+ A simple plugin to add a timestamp overlay to napari
11
+ uses some private overlay functionality, so may break in the future
12
+
13
+ ----------------------------------
14
+
15
+ This [napari] plugin was generated with [Cookiecutter] using [@napari]'s [cookiecutter-napari-plugin] template.
16
+
17
+ ## Installation
18
+
19
+ You can install `napari-timestamper` via [pip]: [not yet on PyPI]
20
+
21
+ pip install napari-timestamper
22
+
23
+
24
+
25
+ To install latest development version :
26
+
27
+ pip install git+https://github.com/bgraedel/napari-timestamper.git
28
+
29
+
30
+ ## Contributing
31
+
32
+ Contributions are very welcome. Tests can be run with [tox], please ensure
33
+ the coverage at least stays the same before you submit a pull request.
34
+
35
+ ## License
36
+
37
+ Distributed under the terms of the [BSD-3] license,
38
+ "napari-timestamper" is free and open source software
39
+
40
+ ## Issues
41
+
42
+ If you encounter any problems, please [file an issue] along with a detailed description.
43
+
44
+ [napari]: https://github.com/napari/napari
45
+ [Cookiecutter]: https://github.com/audreyr/cookiecutter
46
+ [@napari]: https://github.com/napari
47
+ [MIT]: http://opensource.org/licenses/MIT
48
+ [BSD-3]: http://opensource.org/licenses/BSD-3-Clause
49
+ [GNU GPL v3.0]: http://www.gnu.org/licenses/gpl-3.0.txt
50
+ [GNU LGPL v3.0]: http://www.gnu.org/licenses/lgpl-3.0.txt
51
+ [Apache Software License 2.0]: http://www.apache.org/licenses/LICENSE-2.0
52
+ [Mozilla Public License 2.0]: https://www.mozilla.org/media/MPL/2.0/index.txt
53
+ [cookiecutter-napari-plugin]: https://github.com/napari/cookiecutter-napari-plugin
54
+
55
+ [file an issue]: https://github.com/bgraedel/napari-timestamper/issues
56
+
57
+ [napari]: https://github.com/napari/napari
58
+ [tox]: https://tox.readthedocs.io/en/latest/
59
+ [pip]: https://pypi.org/project/pip/
60
+ [PyPI]: https://pypi.org/
@@ -0,0 +1,58 @@
1
+ [build-system]
2
+ requires = ["setuptools>=42.0.0", "wheel", "setuptools_scm"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+
6
+ [tool.setuptools_scm]
7
+ write_to = "src/napari_timestamper/_version.py"
8
+
9
+ [tool.black]
10
+ line-length = 79
11
+ target-version = ['py38', 'py39', 'py310']
12
+
13
+
14
+ [tool.ruff]
15
+ line-length = 79
16
+ select = [
17
+ "E", "F", "W", #flake8
18
+ "UP", # pyupgrade
19
+ "I", # isort
20
+ "BLE", # flake8-blind-exception
21
+ "B", # flake8-bugbear
22
+ "A", # flake8-builtins
23
+ "C4", # flake8-comprehensions
24
+ "ISC", # flake8-implicit-str-concat
25
+ "G", # flake8-logging-format
26
+ "PIE", # flake8-pie
27
+ "SIM", # flake8-simplify
28
+ ]
29
+ ignore = [
30
+ "E501", # line too long. let black handle this
31
+ "UP006", "UP007", # type annotation. As using magicgui require runtime type annotation then we disable this.
32
+ "SIM117", # flake8-simplify - some of merged with statements are not looking great with black, reanble after drop python 3.9
33
+ ]
34
+
35
+ exclude = [
36
+ ".bzr",
37
+ ".direnv",
38
+ ".eggs",
39
+ ".git",
40
+ ".mypy_cache",
41
+ ".pants.d",
42
+ ".ruff_cache",
43
+ ".svn",
44
+ ".tox",
45
+ ".venv",
46
+ "__pypackages__",
47
+ "_build",
48
+ "buck-out",
49
+ "build",
50
+ "dist",
51
+ "node_modules",
52
+ "venv",
53
+ "*vendored*",
54
+ "*_vendor*",
55
+ ]
56
+
57
+ target-version = "py38"
58
+ fix = true
@@ -0,0 +1,63 @@
1
+ [metadata]
2
+ name = napari-timestamper
3
+ description = A simple plugin to add a timestamp overlay to napari
4
+ long_description = file: README.md
5
+ long_description_content_type = text/markdown
6
+ url = https://github.com/bgraedel/napari-timestamper
7
+ author = Benjamin Grädel
8
+ author_email = benjamin.graedel@unibe.ch
9
+ license = BSD-3-Clause
10
+ license_files = LICENSE
11
+ classifiers =
12
+ Development Status :: 2 - Pre-Alpha
13
+ Intended Audience :: Developers
14
+ License :: OSI Approved :: BSD License
15
+ Operating System :: OS Independent
16
+ Programming Language :: Python
17
+ Programming Language :: Python :: 3
18
+ Programming Language :: Python :: 3 :: Only
19
+ Programming Language :: Python :: 3.8
20
+ Programming Language :: Python :: 3.9
21
+ Programming Language :: Python :: 3.10
22
+ Programming Language :: Python :: 3.11
23
+ Topic :: Scientific/Engineering :: Image Processing
24
+ project_urls =
25
+ Bug Tracker = https://github.com/bgraedel/napari-timestamper/issues
26
+ Documentation = https://github.com/bgraedel/napari-timestamper#README.md
27
+ Source Code = https://github.com/bgraedel/napari-timestamper
28
+ User Support = https://github.com/bgraedel/napari-timestamper/issues
29
+
30
+ [options]
31
+ packages = find:
32
+ install_requires =
33
+ numpy
34
+ qtpy
35
+ python_requires = >=3.8
36
+ include_package_data = True
37
+ package_dir =
38
+ =src
39
+ setup_requires = setuptools_scm
40
+
41
+ [options.packages.find]
42
+ where = src
43
+
44
+ [options.entry_points]
45
+ napari.manifest =
46
+ napari-timestamper = napari_timestamper:napari.yaml
47
+
48
+ [options.extras_require]
49
+ testing =
50
+ tox
51
+ pytest # https://docs.pytest.org/en/latest/contents.html
52
+ pytest-cov # https://pytest-cov.readthedocs.io/en/latest/
53
+ pytest-qt # https://pytest-qt.readthedocs.io/en/latest/
54
+ napari
55
+ pyqt5
56
+
57
+ [options.package_data]
58
+ * = *.yaml
59
+
60
+ [egg_info]
61
+ tag_build =
62
+ tag_date = 0
63
+
@@ -0,0 +1,7 @@
1
+ try:
2
+ from ._version import version as __version__
3
+ except ImportError:
4
+ __version__ = "unknown"
5
+ from ._widget import TimestampWidget
6
+
7
+ __all__ = ("TimestampWidget",)
@@ -0,0 +1,15 @@
1
+ from napari_timestamper._timestamp_overlay import (
2
+ TimestampOverlay,
3
+ VispyTimestampOverlay,
4
+ )
5
+
6
+
7
+ def test_timestamp_overlay():
8
+ overlay = TimestampOverlay()
9
+ assert overlay is not None
10
+
11
+
12
+ def test_text_instantiation(make_napari_viewer):
13
+ viewer = make_napari_viewer()
14
+ model = TimestampOverlay()
15
+ VispyTimestampOverlay(overlay=model, viewer=viewer)
@@ -0,0 +1,67 @@
1
+ import pytest
2
+ from qtpy import QtCore
3
+
4
+ from napari_timestamper._widget import TimestampWidget
5
+
6
+
7
+ @pytest.fixture
8
+ def timestamp_options(make_napari_viewer, qtbot):
9
+ viewer = make_napari_viewer()
10
+ widget = TimestampWidget(viewer)
11
+ viewer.window.add_dock_widget(widget)
12
+ return widget
13
+
14
+
15
+ def test_initial_values(timestamp_options):
16
+ assert timestamp_options.time_axis.value() == 0
17
+ assert timestamp_options.start_time.value() == 0
18
+ assert timestamp_options.step_time.value() == 1
19
+ assert timestamp_options.prefix.text() == ""
20
+ assert timestamp_options.suffix.text() == "HH:MM:SS"
21
+ assert timestamp_options.position.currentText() == "top_center"
22
+ assert timestamp_options.ts_size.value() == 12
23
+ assert timestamp_options.x_shift.value() == 0
24
+ assert timestamp_options.y_shift.value() == 0
25
+ assert timestamp_options.time_format.currentText() == "HH:MM:SS"
26
+
27
+
28
+ def test_set_color(timestamp_options, qtbot):
29
+ assert timestamp_options.chosen_color == "white"
30
+ qtbot.mouseClick(timestamp_options.color, QtCore.Qt.LeftButton)
31
+ timestamp_options.color_dialog.done(1)
32
+ assert timestamp_options.chosen_color != "white"
33
+
34
+
35
+ def test_set_timestamp_overlay_options(timestamp_options):
36
+ timestamp_options.time_axis.setValue(1)
37
+ timestamp_options.start_time.setValue(10)
38
+ timestamp_options.step_time.setValue(2)
39
+ timestamp_options.prefix.setText("Time =")
40
+ timestamp_options.suffix.setText("s")
41
+ timestamp_options.position.setCurrentIndex(2)
42
+ timestamp_options.ts_size.setValue(20)
43
+ timestamp_options.x_shift.setValue(5)
44
+ timestamp_options.y_shift.setValue(-5)
45
+ timestamp_options.time_format.setCurrentIndex(1)
46
+
47
+ timestamp_options._set_timestamp_overlay_options()
48
+
49
+ assert timestamp_options.viewer._overlays["timestamp"].time_axis == 1
50
+ assert timestamp_options.viewer._overlays["timestamp"].start_time == 10
51
+ assert timestamp_options.viewer._overlays["timestamp"].step_size == 2
52
+ assert timestamp_options.viewer._overlays["timestamp"].prefix == "Time ="
53
+ assert timestamp_options.viewer._overlays["timestamp"].suffix == "s"
54
+ assert (
55
+ timestamp_options.viewer._overlays["timestamp"].position == "top_right"
56
+ )
57
+ assert timestamp_options.viewer._overlays["timestamp"].size == 20
58
+ assert (
59
+ timestamp_options.viewer._overlays["timestamp"].x_position_offset == 5
60
+ )
61
+ assert (
62
+ timestamp_options.viewer._overlays["timestamp"].y_position_offset == -5
63
+ )
64
+ assert (
65
+ timestamp_options.viewer._overlays["timestamp"].time_format
66
+ == "HH:MM:SS.ss"
67
+ )
@@ -0,0 +1,233 @@
1
+ """
2
+ This module contains the TimestampOverlay class and the VispyTimestampOverlay class.
3
+
4
+ The TimestampOverlay class is a canvas overlay that displays a timestamp on a napari viewer.
5
+ It has several customizable properties such as color, size, prefix, suffix, time, start_time, step_size,
6
+ time_format, y_position_offset, x_position_offset, and time_axis.
7
+
8
+ The VispyTimestampOverlay class is a vispy canvas overlay that displays the TimestampOverlay on a napari viewer.
9
+ It inherits from the ViewerOverlayMixin and VispyCanvasOverlay classes.
10
+
11
+ This structure is adapted from the napari dev example.
12
+ """
13
+ from typing import TYPE_CHECKING
14
+
15
+ from napari._vispy.overlays.base import ViewerOverlayMixin, VispyCanvasOverlay
16
+ from napari.components._viewer_constants import CanvasPosition
17
+ from napari.components.overlays import CanvasOverlay
18
+ from napari.utils.color import ColorValue
19
+ from vispy.scene.visuals import Text
20
+
21
+ if TYPE_CHECKING:
22
+ pass
23
+
24
+
25
+ class TimestampOverlay(CanvasOverlay):
26
+ """
27
+ Timestamp Overlay.
28
+ """
29
+
30
+ color: ColorValue = (0, 1, 0, 1)
31
+ size: int = 10
32
+ prefix: str = ""
33
+ suffix: str = "MM:SS"
34
+ time: int = 0
35
+ start_time: int = 0
36
+ step_size: float = 1
37
+ time_format: str = "MM:SS"
38
+ y_position_offset: int = 0
39
+ x_position_offset: int = 0
40
+ time_axis: int = 0
41
+
42
+ def _timestamp_string(self):
43
+ """
44
+ Returns the formatted timestamp string.
45
+
46
+ Returns
47
+ -------
48
+ str
49
+ The formatted timestamp string.
50
+ """
51
+ timestamp = self._format_timestamp(self.time, self.time_format)
52
+ return f"{self.prefix} {timestamp} {self.suffix}"
53
+
54
+ def _format_timestamp(self, total_time, format_specifier):
55
+ """
56
+ Formats the timestamp string based on the format specifier.
57
+
58
+ Parameters
59
+ ----------
60
+ total_time : int
61
+ The total time in seconds.
62
+ format_specifier : str
63
+ The format specifier for the timestamp text.
64
+
65
+ Returns
66
+ -------
67
+ str
68
+ The formatted timestamp string.
69
+ """
70
+ time = float(self.start_time + self.time * self.step_size)
71
+ hours = int(time // 3600)
72
+ minutes = int((time % 3600) // 60)
73
+ seconds = time % 60
74
+
75
+ if format_specifier == "HH:MM:SS":
76
+ return f"{hours:02}:{minutes:02}:{seconds:02.0f}"
77
+ if format_specifier == "HH:MM:SS.ss":
78
+ return f"{hours:02}:{minutes:02}:{seconds:05.2f}"
79
+ elif format_specifier == "H:M:S":
80
+ return f"{hours}:{minutes}:{seconds:.0f}"
81
+ elif format_specifier == "H:M:S.ss":
82
+ return f"{hours}:{minutes}:{seconds:.2f}"
83
+ elif format_specifier == "MM:SS":
84
+ return f"{minutes:02}:{seconds:02.0f}"
85
+ elif format_specifier == "MM:SS.ss":
86
+ return f"{minutes:02}:{seconds:05.2f}"
87
+ elif format_specifier == "M:S":
88
+ return f"{minutes}:{seconds:.0f}"
89
+ elif format_specifier == "M:S.ss":
90
+ return f"{minutes}:{seconds:.2f}"
91
+ elif format_specifier == "SS":
92
+ return f"{total_time:02.0f}"
93
+ elif format_specifier == "SS.ss":
94
+ return f"{total_time:05.2f}"
95
+ elif format_specifier == "F":
96
+ return f"{total_time:.0f}"
97
+ else:
98
+ raise ValueError(f"Unknown format specifier: {format_specifier}")
99
+
100
+ def _get_allowed_format_specifiers():
101
+ """
102
+ Returns a list of allowed format specifiers.
103
+
104
+ Returns
105
+ -------
106
+ list of str
107
+ A list of allowed format specifiers.
108
+ """
109
+ return [
110
+ "HH:MM:SS",
111
+ "HH:MM:SS.ss",
112
+ "H:M:S",
113
+ "H:M:S.ss",
114
+ "MM:SS",
115
+ "MM:SS.ss",
116
+ "M:S",
117
+ "M:S.ss",
118
+ "SS",
119
+ "SS.ss",
120
+ "F",
121
+ ]
122
+
123
+ @property
124
+ def text(self):
125
+ """
126
+ Returns the formatted timestamp string.
127
+
128
+ Returns
129
+ -------
130
+ str
131
+ The formatted timestamp string.
132
+ """
133
+ return self._timestamp_string()
134
+
135
+
136
+ class VispyTimestampOverlay(ViewerOverlayMixin, VispyCanvasOverlay):
137
+ """
138
+ Vispy Timestamp Overlay.
139
+ """
140
+
141
+ def __init__(self, *, viewer, overlay, parent=None):
142
+ super().__init__(
143
+ node=Text(
144
+ text=overlay.text,
145
+ color=overlay.color,
146
+ font_size=overlay.size,
147
+ pos=(0, 0),
148
+ ),
149
+ viewer=viewer,
150
+ overlay=overlay,
151
+ parent=parent,
152
+ )
153
+
154
+ # setup callbacks
155
+ self.overlay.events.color.connect(self._on_color_change)
156
+ self.overlay.events.size.connect(self._on_size_change)
157
+ self.overlay.events.text.connect(self._on_text_change)
158
+ self.overlay.events.y_position_offset.connect(self._on_position_change)
159
+ self.overlay.events.x_position_offset.connect(self._on_position_change)
160
+ self.overlay.events.time_format.connect(self._on_text_change)
161
+ self.overlay.events.start_time.connect(self._on_time_change)
162
+ self.overlay.events.step_size.connect(self._on_time_change)
163
+ self.overlay.events.prefix.connect(self._on_text_change)
164
+ self.overlay.events.suffix.connect(self._on_text_change)
165
+ self.overlay.events.time_axis.connect(self._on_text_change)
166
+ self.viewer.dims.events.current_step.connect(self._on_time_change)
167
+
168
+ self.reset()
169
+
170
+ def _on_color_change(self, event=None):
171
+ """
172
+ Callback function for when the color of the overlay is changed.
173
+ """
174
+ self.node.color = self.overlay.color
175
+
176
+ def _on_position_change(self, event=None):
177
+ """
178
+ Callback function for when the position of the overlay is changed.
179
+ """
180
+ super()._on_position_change()
181
+ position = self.overlay.position
182
+
183
+ if position == CanvasPosition.TOP_LEFT:
184
+ anchors = ("left", "bottom")
185
+ elif position == CanvasPosition.TOP_RIGHT:
186
+ anchors = ("right", "bottom")
187
+ elif position == CanvasPosition.TOP_CENTER:
188
+ anchors = ("center", "bottom")
189
+ elif position == CanvasPosition.BOTTOM_RIGHT:
190
+ anchors = ("right", "top")
191
+ elif position == CanvasPosition.BOTTOM_LEFT:
192
+ anchors = ("left", "top")
193
+ elif position == CanvasPosition.BOTTOM_CENTER:
194
+ anchors = ("center", "top")
195
+
196
+ self.node.anchors = anchors
197
+ self.node.pos = (
198
+ self.overlay.x_position_offset,
199
+ self.overlay.y_position_offset,
200
+ )
201
+
202
+ def _on_size_change(self, event=None):
203
+ """
204
+ Callback function for when the size of the overlay is changed.
205
+ """
206
+ self.node.font_size = self.overlay.size
207
+ self._on_position_change()
208
+
209
+ def _on_text_change(self, event=None):
210
+ """
211
+ Callback function for when the text of the overlay is changed.
212
+ """
213
+ self.node.text = self.overlay.text
214
+
215
+ def _on_time_change(self, event=None):
216
+ """
217
+ Callback function for when the time of the overlay is changed.
218
+ """
219
+ self.overlay.time = self.viewer.dims.current_step[
220
+ self.overlay.time_axis
221
+ ]
222
+ self.node.text = self.overlay.text
223
+
224
+ def reset(self):
225
+ """
226
+ Resets the overlay to its initial state.
227
+ """
228
+ super().reset()
229
+ self._on_color_change()
230
+ self._on_size_change()
231
+ self._on_position_change()
232
+ self._on_text_change()
233
+ self._on_time_change()
@@ -0,0 +1,4 @@
1
+ # file generated by setuptools_scm
2
+ # don't change, don't track in version control
3
+ __version__ = version = '0.0.1'
4
+ __version_tuple__ = version_tuple = (0, 0, 1)
@@ -0,0 +1,220 @@
1
+ """
2
+ Dock widget for napari-timestamper
3
+ """
4
+ from __future__ import annotations
5
+
6
+ import warnings
7
+
8
+ import napari
9
+ from napari._vispy.utils.visual import overlay_to_visual
10
+ from napari.components._viewer_constants import CanvasPosition
11
+ from qtpy import QtWidgets
12
+
13
+ from napari_timestamper._timestamp_overlay import (
14
+ TimestampOverlay,
15
+ VispyTimestampOverlay,
16
+ )
17
+
18
+
19
+ class TimestampWidget(QtWidgets.QWidget):
20
+ """
21
+ A widget that provides options for the timestamp overlay in napari viewer.
22
+
23
+ Parameters
24
+ ----------
25
+ viewer : napari.Viewer
26
+ The napari viewer instance.
27
+ parent : QWidget, optional
28
+ The parent widget, by default None.
29
+ """
30
+
31
+ overlay_set: bool = False
32
+
33
+ def __init__(self, viewer: napari.viewer.Viewer, parent=None):
34
+ """
35
+ Initialize the timestamp_options widget.
36
+
37
+ Parameters
38
+ ----------
39
+ viewer : napari.Viewer
40
+ The napari viewer instance.
41
+ parent : QWidget, optional
42
+ The parent widget, by default None.
43
+ """
44
+ super().__init__(parent)
45
+ self.chosen_color = "white"
46
+ self.viewer = viewer
47
+ self._setupUi()
48
+ self._connect_all_changes()
49
+ self._setup_overlay()
50
+
51
+ def _setup_overlay(self):
52
+ with warnings.catch_warnings():
53
+ warnings.simplefilter("ignore")
54
+ try:
55
+ self.viewer._overlays["timestamp"]
56
+ except KeyError:
57
+ self.viewer._overlays["timestamp"] = TimestampOverlay(
58
+ visible=True
59
+ )
60
+ overlay_to_visual[TimestampOverlay] = VispyTimestampOverlay
61
+ self.viewer.window._qt_viewer._add_overlay(
62
+ self.viewer._overlays["timestamp"]
63
+ )
64
+ self.timestamp_overlay = self.viewer._overlays["timestamp"]
65
+ self._set_timestamp_overlay_options()
66
+ self.overlay_set = True
67
+
68
+ def _toggle_overlay(self):
69
+ if not self.overlay_set:
70
+ self._setup_overlay()
71
+ self.toggle_timestamp.setText("Remove Timestamp")
72
+ return
73
+
74
+ if self.timestamp_overlay.visible:
75
+ self.timestamp_overlay.visible = False
76
+ self.toggle_timestamp.setText("Add Timestamp")
77
+ else:
78
+ self.timestamp_overlay.visible = True
79
+ self.toggle_timestamp.setText("Remove Timestamp")
80
+
81
+ def _setupUi(self):
82
+ self.setObjectName("Timestamp Options")
83
+ self.gridLayout = QtWidgets.QGridLayout()
84
+
85
+ self.time_axis_label = QtWidgets.QLabel("Time Axis")
86
+ self.time_axis = QtWidgets.QSpinBox()
87
+ self.time_axis.setRange(-10, 10)
88
+
89
+ self.start_time_label = QtWidgets.QLabel("Start Time")
90
+ self.start_time = QtWidgets.QSpinBox()
91
+ self.start_time.setRange(0, 10000)
92
+ self.start_time.setValue(0)
93
+
94
+ self.step_time_label = QtWidgets.QLabel("Step Time")
95
+ self.step_time = QtWidgets.QDoubleSpinBox()
96
+ self.step_time.setRange(0, 10000)
97
+ self.step_time.setValue(1)
98
+
99
+ self.prefix_label = QtWidgets.QLabel("Prefix")
100
+ self.prefix = QtWidgets.QLineEdit()
101
+ self.prefix.setText("")
102
+
103
+ self.suffix_label = QtWidgets.QLabel("Suffix")
104
+ self.suffix = QtWidgets.QLineEdit()
105
+ self.suffix.setText("HH:MM:SS")
106
+
107
+ self.position_label = QtWidgets.QLabel("Position")
108
+ self.position = QtWidgets.QComboBox()
109
+ self.position.addItems(CanvasPosition)
110
+ self.position.setCurrentIndex(1)
111
+
112
+ self.size_label = QtWidgets.QLabel("Size")
113
+ self.ts_size = QtWidgets.QSpinBox()
114
+ self.ts_size.setRange(0, 1000)
115
+ self.ts_size.setValue(12)
116
+
117
+ self.shift_label = QtWidgets.QLabel("XY Shift")
118
+ self.shiftlayout = QtWidgets.QHBoxLayout()
119
+ self.x_shift = QtWidgets.QSpinBox()
120
+ self.x_shift.setRange(-1000, 1000)
121
+ self.x_shift.setValue(0)
122
+ self.y_shift = QtWidgets.QSpinBox()
123
+ self.y_shift.setRange(-1000, 1000)
124
+ self.y_shift.setValue(0)
125
+ self.shiftlayout.addWidget(self.x_shift)
126
+ self.shiftlayout.addWidget(self.y_shift)
127
+
128
+ self.time_format_label = QtWidgets.QLabel("Time Format")
129
+ self.time_format = QtWidgets.QComboBox()
130
+ self.time_format.addItems(
131
+ TimestampOverlay._get_allowed_format_specifiers()
132
+ )
133
+
134
+ self.color = QtWidgets.QPushButton("Choose Color")
135
+ self.color_display = QtWidgets.QFrame()
136
+
137
+ self.toggle_timestamp = QtWidgets.QPushButton("Add Timestamp")
138
+
139
+ self.gridLayout.addWidget(self.time_axis_label, 0, 0)
140
+ self.gridLayout.addWidget(self.time_axis, 0, 1)
141
+ self.gridLayout.addWidget(self.start_time_label, 1, 0)
142
+ self.gridLayout.addWidget(self.start_time, 1, 1)
143
+ self.gridLayout.addWidget(self.step_time_label, 2, 0)
144
+ self.gridLayout.addWidget(self.step_time, 2, 1)
145
+ self.gridLayout.addWidget(self.prefix_label, 3, 0)
146
+ self.gridLayout.addWidget(self.prefix, 3, 1)
147
+ self.gridLayout.addWidget(self.suffix_label, 4, 0)
148
+ self.gridLayout.addWidget(self.suffix, 4, 1)
149
+ self.gridLayout.addWidget(self.position_label, 5, 0)
150
+ self.gridLayout.addWidget(self.position, 5, 1)
151
+ self.gridLayout.addWidget(self.size_label, 6, 0)
152
+ self.gridLayout.addWidget(self.ts_size, 6, 1)
153
+ self.gridLayout.addWidget(self.shift_label, 7, 0)
154
+ self.gridLayout.addLayout(self.shiftlayout, 7, 1)
155
+ self.gridLayout.addWidget(self.time_format_label, 8, 0)
156
+ self.gridLayout.addWidget(self.time_format, 8, 1)
157
+ self.gridLayout.addWidget(self.color, 9, 1)
158
+ self.gridLayout.addWidget(self.color_display, 9, 0)
159
+ self.gridLayout.addWidget(self.toggle_timestamp, 10, 0, 1, 2)
160
+ self.setLayout(self.gridLayout)
161
+
162
+ self.spacer = QtWidgets.QSpacerItem(
163
+ 20,
164
+ 40,
165
+ QtWidgets.QSizePolicy.Minimum,
166
+ QtWidgets.QSizePolicy.Expanding,
167
+ )
168
+ self.gridLayout.addItem(self.spacer, 11, 0, 1, 2)
169
+
170
+ self.color_display.setStyleSheet(
171
+ "QWidget {background-color: %s}" % self.chosen_color
172
+ )
173
+
174
+ def _open_color_dialog(self):
175
+ self.color_dialog = QtWidgets.QColorDialog(parent=self)
176
+ self.color_dialog.open(self._set_colour)
177
+
178
+ def _set_colour(self):
179
+ color = self.color_dialog.selectedColor()
180
+ if color.isValid():
181
+ self.color_display.setStyleSheet(
182
+ "QWidget {background-color: %s}" % color.name()
183
+ )
184
+ self.chosen_color = color.name()
185
+ self._set_timestamp_overlay_options()
186
+
187
+ def _set_timestamp_overlay_options(self):
188
+ with warnings.catch_warnings():
189
+ warnings.simplefilter("ignore")
190
+ timestamp_overlay = self.viewer._overlays["timestamp"]
191
+ timestamp_overlay.color = self.chosen_color
192
+ timestamp_overlay.size = self.ts_size.value()
193
+ timestamp_overlay.position = self.position.currentText()
194
+ timestamp_overlay.prefix = self.prefix.text()
195
+ timestamp_overlay.suffix = self.suffix.text()
196
+ timestamp_overlay.start_time = self.start_time.value()
197
+ timestamp_overlay.step_size = self.step_time.value()
198
+ timestamp_overlay.time_format = self.time_format.currentText()
199
+ timestamp_overlay.x_position_offset = self.x_shift.value()
200
+ timestamp_overlay.y_position_offset = self.y_shift.value()
201
+ timestamp_overlay.time_axis = self.time_axis.value()
202
+
203
+ def _connect_all_changes(self):
204
+ for i in [
205
+ self.time_axis,
206
+ self.start_time,
207
+ self.step_time,
208
+ self.ts_size,
209
+ self.x_shift,
210
+ self.y_shift,
211
+ ]:
212
+ i.valueChanged.connect(self._set_timestamp_overlay_options)
213
+ for i in [self.prefix, self.suffix]:
214
+ i.textChanged.connect(self._set_timestamp_overlay_options)
215
+ for i in [self.position, self.time_format]:
216
+ i.currentTextChanged.connect(self._set_timestamp_overlay_options)
217
+ self.toggle_timestamp.clicked.connect(self._toggle_overlay)
218
+
219
+ self.color.clicked.connect(self._open_color_dialog)
220
+ self.color.clicked.connect(self._set_timestamp_overlay_options)
@@ -0,0 +1,10 @@
1
+ name: napari-timestamper
2
+ display_name: Timestamper
3
+ contributions:
4
+ commands:
5
+ - id: napari-timestamper.timestamper
6
+ python_name: napari_timestamper._widget:TimestampWidget
7
+ title: Make Timestamp Widget
8
+ widgets:
9
+ - command: napari-timestamper.timestamper
10
+ display_name: Timestamper
@@ -0,0 +1,89 @@
1
+ Metadata-Version: 2.1
2
+ Name: napari-timestamper
3
+ Version: 0.0.1
4
+ Summary: A simple plugin to add a timestamp overlay to napari
5
+ Home-page: https://github.com/bgraedel/napari-timestamper
6
+ Author: Benjamin Grädel
7
+ Author-email: benjamin.graedel@unibe.ch
8
+ License: BSD-3-Clause
9
+ Project-URL: Bug Tracker, https://github.com/bgraedel/napari-timestamper/issues
10
+ Project-URL: Documentation, https://github.com/bgraedel/napari-timestamper#README.md
11
+ Project-URL: Source Code, https://github.com/bgraedel/napari-timestamper
12
+ Project-URL: User Support, https://github.com/bgraedel/napari-timestamper/issues
13
+ Classifier: Development Status :: 2 - Pre-Alpha
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: BSD License
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python
18
+ Classifier: Programming Language :: Python :: 3
19
+ Classifier: Programming Language :: Python :: 3 :: Only
20
+ Classifier: Programming Language :: Python :: 3.8
21
+ Classifier: Programming Language :: Python :: 3.9
22
+ Classifier: Programming Language :: Python :: 3.10
23
+ Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
25
+ Requires-Python: >=3.8
26
+ Description-Content-Type: text/markdown
27
+ Provides-Extra: testing
28
+ License-File: LICENSE
29
+
30
+ # napari-timestamper
31
+
32
+ [![License BSD-3](https://img.shields.io/pypi/l/napari-timestamper.svg?color=green)](https://github.com/bgraedel/napari-timestamper/raw/main/LICENSE)
33
+ [![PyPI](https://img.shields.io/pypi/v/napari-timestamper.svg?color=green)](https://pypi.org/project/napari-timestamper)
34
+ [![Python Version](https://img.shields.io/pypi/pyversions/napari-timestamper.svg?color=green)](https://python.org)
35
+ [![tests](https://github.com/bgraedel/napari-timestamper/workflows/tests/badge.svg)](https://github.com/bgraedel/napari-timestamper/actions)
36
+ [![codecov](https://codecov.io/gh/bgraedel/napari-timestamper/branch/main/graph/badge.svg)](https://codecov.io/gh/bgraedel/napari-timestamper)
37
+ <!-- [![napari hub](https://img.shields.io/endpoint?url=https://api.napari-hub.org/shields/napari-timestamper)](https://napari-hub.org/plugins/napari-timestamper) -->
38
+
39
+ A simple plugin to add a timestamp overlay to napari
40
+ uses some private overlay functionality, so may break in the future
41
+
42
+ ----------------------------------
43
+
44
+ This [napari] plugin was generated with [Cookiecutter] using [@napari]'s [cookiecutter-napari-plugin] template.
45
+
46
+ ## Installation
47
+
48
+ You can install `napari-timestamper` via [pip]: [not yet on PyPI]
49
+
50
+ pip install napari-timestamper
51
+
52
+
53
+
54
+ To install latest development version :
55
+
56
+ pip install git+https://github.com/bgraedel/napari-timestamper.git
57
+
58
+
59
+ ## Contributing
60
+
61
+ Contributions are very welcome. Tests can be run with [tox], please ensure
62
+ the coverage at least stays the same before you submit a pull request.
63
+
64
+ ## License
65
+
66
+ Distributed under the terms of the [BSD-3] license,
67
+ "napari-timestamper" is free and open source software
68
+
69
+ ## Issues
70
+
71
+ If you encounter any problems, please [file an issue] along with a detailed description.
72
+
73
+ [napari]: https://github.com/napari/napari
74
+ [Cookiecutter]: https://github.com/audreyr/cookiecutter
75
+ [@napari]: https://github.com/napari
76
+ [MIT]: http://opensource.org/licenses/MIT
77
+ [BSD-3]: http://opensource.org/licenses/BSD-3-Clause
78
+ [GNU GPL v3.0]: http://www.gnu.org/licenses/gpl-3.0.txt
79
+ [GNU LGPL v3.0]: http://www.gnu.org/licenses/lgpl-3.0.txt
80
+ [Apache Software License 2.0]: http://www.apache.org/licenses/LICENSE-2.0
81
+ [Mozilla Public License 2.0]: https://www.mozilla.org/media/MPL/2.0/index.txt
82
+ [cookiecutter-napari-plugin]: https://github.com/napari/cookiecutter-napari-plugin
83
+
84
+ [file an issue]: https://github.com/bgraedel/napari-timestamper/issues
85
+
86
+ [napari]: https://github.com/napari/napari
87
+ [tox]: https://tox.readthedocs.io/en/latest/
88
+ [pip]: https://pypi.org/project/pip/
89
+ [PyPI]: https://pypi.org/
@@ -0,0 +1,26 @@
1
+ .gitignore
2
+ .pre-commit-config.yaml
3
+ 42.0.0
4
+ LICENSE
5
+ MANIFEST.in
6
+ README.md
7
+ pyproject.toml
8
+ setup.cfg
9
+ tox.ini
10
+ .github/workflows/test_and_deploy.yml
11
+ .napari-hub/DESCRIPTION.md
12
+ .napari-hub/config.yml
13
+ src/napari_timestamper/__init__.py
14
+ src/napari_timestamper/_timestamp_overlay.py
15
+ src/napari_timestamper/_version.py
16
+ src/napari_timestamper/_widget.py
17
+ src/napari_timestamper/napari.yaml
18
+ src/napari_timestamper.egg-info/PKG-INFO
19
+ src/napari_timestamper.egg-info/SOURCES.txt
20
+ src/napari_timestamper.egg-info/dependency_links.txt
21
+ src/napari_timestamper.egg-info/entry_points.txt
22
+ src/napari_timestamper.egg-info/requires.txt
23
+ src/napari_timestamper.egg-info/top_level.txt
24
+ src/napari_timestamper/_tests/__init__.py
25
+ src/napari_timestamper/_tests/test_timestamp_overlay.py
26
+ src/napari_timestamper/_tests/test_widget.py
@@ -0,0 +1,2 @@
1
+ [napari.manifest]
2
+ napari-timestamper = napari_timestamper:napari.yaml
@@ -0,0 +1,10 @@
1
+ numpy
2
+ qtpy
3
+
4
+ [testing]
5
+ tox
6
+ pytest
7
+ pytest-cov
8
+ pytest-qt
9
+ napari
10
+ pyqt5
@@ -0,0 +1 @@
1
+ napari_timestamper
@@ -0,0 +1,32 @@
1
+ [tox]
2
+ envlist = py{38,39,310}-{linux,macos,windows}
3
+ isolated_build=true
4
+
5
+ [gh-actions]
6
+ python =
7
+ 3.8: py38
8
+ 3.9: py39
9
+ 3.10: py310
10
+
11
+
12
+ [gh-actions:env]
13
+ PLATFORM =
14
+ ubuntu-latest: linux
15
+ macos-latest: macos
16
+ windows-latest: windows
17
+
18
+ [testenv]
19
+ platform =
20
+ macos: darwin
21
+ linux: linux
22
+ windows: win32
23
+ passenv =
24
+ CI
25
+ GITHUB_ACTIONS
26
+ DISPLAY
27
+ XAUTHORITY
28
+ NUMPY_EXPERIMENTAL_ARRAY_FUNCTION
29
+ PYVISTA_OFF_SCREEN
30
+ extras =
31
+ testing
32
+ commands = pytest -v --color=yes --cov=napari_timestamper --cov-report=xml