diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..865cb3e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,31 @@ +--- +name: Bug report +about: Create a report to help us improve +title: '' +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + - OS: [e.g. macOS Catalina, Windows 10 1903, Ubuntu 19.10] + - Python Video Annotator Version [e.g. 3.306] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..bbcbbe7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,20 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: '' +labels: '' +assignees: '' + +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.gitmodules b/.gitmodules index 0c047d7..ed580eb 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,76 +1,73 @@ [submodule "base/pythonvideoannotator-models"] path = base/pythonvideoannotator-models - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-models.git + url = https://github.com/video-annotator/pythonvideoannotator-models.git [submodule "base/pythonvideoannotator-models-gui"] path = base/pythonvideoannotator-models-gui - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-models-gui.git + url = https://github.com/video-annotator/pythonvideoannotator-models-gui.git [submodule "plugins/pythonvideoannotator-module-backgroundfinder"] path = plugins/pythonvideoannotator-module-backgroundfinder - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-backgroundfinder.git + url = https://github.com/video-annotator/pythonvideoannotator-module-backgroundfinder.git [submodule "libraries/mcv-api"] path = libraries/mcv-api - url = https://bitbucket.org/fchampalimaud/mcv-api.git + url = https://github.com/video-annotator/mcv-api.git [submodule "libraries/mcv-gui"] path = libraries/mcv-gui - url = https://bitbucket.org/fchampalimaud/mcv-gui.git -[submodule "libraries/mcv-gui-editor"] - path = libraries/mcv-gui-editor - url = https://bitbucket.org/fchampalimaud/mcv-gui-editor.git + url = https://github.com/video-annotator/mcv-gui.git [submodule "libraries/confapp"] path = libraries/confapp url = https://github.com/UmSenhorQualquer/confapp.git [submodule "plugins/pythonvideoannotator-module-contoursimages"] path = plugins/pythonvideoannotator-module-contoursimages - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-contoursimages.git + url = https://github.com/video-annotator/pythonvideoannotator-module-contoursimages.git [submodule "plugins/pythonvideoannotator-module-createpaths"] path = plugins/pythonvideoannotator-module-createpaths - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-createpaths.git + url = https://github.com/video-annotator/pythonvideoannotator-module-createpaths.git [submodule "plugins/pythonvideoannotator-module-distances"] path = plugins/pythonvideoannotator-module-distances - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-distances.git + url = https://github.com/video-annotator/pythonvideoannotator-module-distances.git [submodule "plugins/pythonvideoannotator-module-eventsstats"] path = plugins/pythonvideoannotator-module-eventsstats - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-eventsstats.git + url = https://github.com/video-annotator/pythonvideoannotator-module-eventsstats.git [submodule "plugins/pythonvideoannotator-module-findorientation"] path = plugins/pythonvideoannotator-module-findorientation - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-findorientation.git + url = https://github.com/video-annotator/pythonvideoannotator-module-findorientation.git [submodule "plugins/pythonvideoannotator-module-importexport"] path = plugins/pythonvideoannotator-module-importexport - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-importexport.git + url = https://github.com/video-annotator/pythonvideoannotator-module-importexport.git [submodule "plugins/pythonvideoannotator-module-motioncounter"] path = plugins/pythonvideoannotator-module-motioncounter - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-motioncounter.git + url = https://github.com/video-annotator/pythonvideoannotator-module-motioncounter.git [submodule "plugins/pythonvideoannotator-module-patheditor"] path = plugins/pythonvideoannotator-module-patheditor - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-patheditor.git + url = https://github.com/video-annotator/pythonvideoannotator-module-patheditor.git [submodule "plugins/pythonvideoannotator-module-regionsfilter"] path = plugins/pythonvideoannotator-module-regionsfilter - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-regionsfilter.git + url = https://github.com/video-annotator/pythonvideoannotator-module-regionsfilter.git [submodule "plugins/pythonvideoannotator-module-smoothpaths"] path = plugins/pythonvideoannotator-module-smoothpaths - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-smoothpaths.git + url = https://github.com/video-annotator/pythonvideoannotator-module-smoothpaths.git [submodule "plugins/pythonvideoannotator-module-timeline"] path = plugins/pythonvideoannotator-module-timeline - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-timeline.git + url = https://github.com/video-annotator/pythonvideoannotator-module-timeline.git [submodule "plugins/pythonvideoannotator-module-tracking"] path = plugins/pythonvideoannotator-module-tracking - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-tracking.git + url = https://github.com/video-annotator/pythonvideoannotator-module-tracking.git [submodule "plugins/pythonvideoannotator-module-virtualobjectgenerator"] path = plugins/pythonvideoannotator-module-virtualobjectgenerator - url = https://bitbucket.org/fchampalimaud/pythonvideoannotator-module-virtualobjectgenerator.git + url = https://github.com/video-annotator/pythonvideoannotator-module-virtualobjectgenerator.git [submodule "libraries/pyforms-gui"] path = libraries/pyforms-gui url = https://github.com/UmSenhorQualquer/pyforms-gui.git [submodule "libraries/geometry-designer"] path = libraries/geometry-designer - url = https://bitbucket.org/fchampalimaud/geometry-designer.git + url = https://github.com/video-annotator/geometry-designer.git [submodule "plugins/pythonvideoannotator-module-pathmap"] path = plugins/pythonvideoannotator-module-pathmap - url = https://UmSenhorQualquer@bitbucket.org/fchampalimaud/pythonvideoannotator-module-pathmap.git + url = https://github.com/video-annotator/pythonvideoannotator-module-pathmap.git [submodule "plugins/pythonvideoannotator-module-deeplab"] path = plugins/pythonvideoannotator-module-deeplab - url = https://manuelmanso@bitbucket.org/fchampalimaud/pythonvideoannotator-module-deeplab.git + url = https://github.com/video-annotator/pythonvideoannotator-module-deeplab.git [submodule "plugins/pythonvideoannotator-module-idtrackerai"] path = plugins/pythonvideoannotator-module-idtrackerai - url = https://github.com/UmSenhorQualquer/pythonvideoannotator-module-idtrackerai.git + url = https://github.com/video-annotator/pythonvideoannotator-module-idtrackerai.git diff --git a/README.md b/README.md index 11e30ac..ab11bf7 100644 --- a/README.md +++ b/README.md @@ -14,40 +14,74 @@ Features: [![Video](docs/youtube.png)](https://www.youtube.com/watch?v=9C4Zr8fhqFo&t=63s) +![Video annotator screenshot](docs/screenshot.png "Screen") -### Developers +## Installation & Running -* Ricardo Ribeiro - collaborator of the [Scientific Software Platform](http://neuro.fchampalimaud.org/en/research/platforms/staff/Scientific%20Software/) of the [Champalimaud Foundation](http://fchampalimaud.org). -* Hugo Cachitas working - collaborator of the [Innate Behavior Lab](http://neuro.fchampalimaud.org/en/research/investigators/research-groups/group/Vasconcelos/) of the [Champalimaud Foundation](http://fchampalimaud.org). -* Carlos Mão de Ferro - collaborator of the [Scientific Software Platform](http://neuro.fchampalimaud.org/en/research/platforms/staff/Scientific%20Software/) of the [Champalimaud Foundation](http://fchampalimaud.org). +How to install: +1. Create a Virtual Environment (highly recommended) on your preferred Python distribution with Python 3.6: + * example with Anaconda in Anaconda Prompt -![Video annotator screenshot](docs/screenshot.png "Screen") + ```bash + conda create -n videoannotator python=3.6 -## Installation & Running + ... -How to install: + conda activate videoannotator + ``` + +2. Make sure you are in the just created virtual environment and install PythonVideoAnnotator with pip: + + ```bash + pip install python-video-annotator + ``` + +If you are having issues (e.g., MacOS Catalina): -1. Install Python 3.6 from [python.org](https://www.python.org/) +1. Start with a fresh Virtual Environment (highly recommended) on your preferred Python distribution with Python 3.6: + * example with Anaconda in Anaconda Prompt -2. Install pypi from [pypi.org](https://pypi.org/) + ```bash + conda create -n videoannotator python=3.6 -3. Install PythonVideoAnnotator from Pypi: -``` -pip install python-video-annotator -``` + ... + + conta activate videoannotator + ``` + +2. Install some of the dependencies that might present issues as: + + ```bash + pip install opencv-python-headless pyqt5==5.14.1 pyqtwebengine==5.14.0 + ``` + +3. Install Python Video Annotator + + ```bash + pip install python-video-annotator + ``` How to run: -``` -start-video-annotator -``` +1. After the installation completes, you can start Python Video Annotator with: + + ```bash + start-video-annotator + ``` -### For developers: +### For developers -[Follow the steps described here](https://pythonvideoannotator.readthedocs.io/en/master/user-docs/install_and_run/install_and_run.html#for-developers) +[Follow the steps described here](https://pythonvideoannotator.readthedocs.io/en/master/user-docs/install_and_run/index.html#for-developers) +## Developers + +* Ricardo Ribeiro - collaborator of the [Scientific Software Platform](http://neuro.fchampalimaud.org/en/research/platforms/staff/Scientific%20Software/) of the [Champalimaud Foundation](http://fchampalimaud.org). +* Hugo Cachitas working - collaborator of the [Innate Behavior Lab](http://neuro.fchampalimaud.org/en/research/investigators/research-groups/group/Vasconcelos/) of the [Champalimaud Foundation](http://fchampalimaud.org). +* Carlos Mão de Ferro - collaborator of the [Scientific Software Platform](http://neuro.fchampalimaud.org/en/research/platforms/staff/Scientific%20Software/) of the [Champalimaud Foundation](http://fchampalimaud.org). +* Luís Teixeira - collaborator of the [Scientific Software Platform](http://neuro.fchampalimaud.org/en/research/platforms/staff/Scientific%20Software/) of the [Champalimaud Foundation](http://fchampalimaud.org). + ## Collaboration This project was initially developed in collaboration with the [Innate Behavior Lab](http://neuro.fchampalimaud.org/en/research/investigators/research-groups/group/Vasconcelos/) to correct the result of a Computer Vision software to track flies in an arena diff --git a/base/pythonvideoannotator-models b/base/pythonvideoannotator-models index f5fe97b..8d56ca0 160000 --- a/base/pythonvideoannotator-models +++ b/base/pythonvideoannotator-models @@ -1 +1 @@ -Subproject commit f5fe97bea804138c80b9192e262319ee0dbb4df3 +Subproject commit 8d56ca075432a880105086fd1950a35a3f0b4ad4 diff --git a/base/pythonvideoannotator-models-gui b/base/pythonvideoannotator-models-gui index df7b9ef..6e0d5b6 160000 --- a/base/pythonvideoannotator-models-gui +++ b/base/pythonvideoannotator-models-gui @@ -1 +1 @@ -Subproject commit df7b9eff58c1d3191a782dbfc42612a4b7363659 +Subproject commit 6e0d5b6acf0a96284e95ffd7a7255b91e4054ab6 diff --git a/base/pythonvideoannotator/pythonvideoannotator/__init__.py b/base/pythonvideoannotator/pythonvideoannotator/__init__.py index a1995d3..cb461bb 100755 --- a/base/pythonvideoannotator/pythonvideoannotator/__init__.py +++ b/base/pythonvideoannotator/pythonvideoannotator/__init__.py @@ -1,7 +1,7 @@ # !/usr/bin/python3 # -*- coding: utf-8 -*- -__version__ = "3.194" +__version__ = "3.306" __author__ = ["Ricardo Ribeiro", "Carlos Mao de Ferro", "Hugo Cachitas"] __credits__ = ["Ricardo Ribeiro", "Carlos Mao de Ferro", "Hugo Cachitas"] __license__ = "Attribution-NonCommercial-ShareAlike 4.0 International" diff --git a/base/pythonvideoannotator/pythonvideoannotator/base_module/base_io.py b/base/pythonvideoannotator/pythonvideoannotator/base_module/base_io.py index 9d0fbda..cacf2d2 100644 --- a/base/pythonvideoannotator/pythonvideoannotator/base_module/base_io.py +++ b/base/pythonvideoannotator/pythonvideoannotator/base_module/base_io.py @@ -20,13 +20,15 @@ def save(self, data, project_path=None): def load(self, data, project_path=None): try: self._project.load(data, project_path) - except FileNotFoundError as e: + except Exception as e: QMessageBox.critical(self, "Error", str(e)) def save_project(self, project_path=None): try: if project_path is None: - project_path = QFileDialog.getExistingDirectory(self, "Select the project directory") + dialog = QFileDialog() + dialog.setLabelText(QFileDialog.Accept, 'Save') + project_path = dialog.getExistingDirectory(self, caption="Select the project directory to save") if project_path is not None and str(project_path) != '': project_path = str(project_path) @@ -37,7 +39,7 @@ def save_project(self, project_path=None): def load_project(self, project_path=None): if project_path is None: - project_path = QFileDialog.getExistingDirectory(self, "Select the project directory") + project_path = QFileDialog.getExistingDirectory(self, caption="Select the project directory to open") if project_path is not None and str(project_path) != '': self.load({}, str(project_path)) diff --git a/base/pythonvideoannotator/pythonvideoannotator/base_module/base_keys_events.py b/base/pythonvideoannotator/pythonvideoannotator/base_module/base_keys_events.py index f00c921..94f099a 100644 --- a/base/pythonvideoannotator/pythonvideoannotator/base_module/base_keys_events.py +++ b/base/pythonvideoannotator/pythonvideoannotator/base_module/base_keys_events.py @@ -32,7 +32,6 @@ def mark_point(self): path.mark_point_button.click() def keyReleaseEvent(self, event): - super().keyReleaseEvent(event) selected = self.project.tree.selected_item diff --git a/base/pythonvideoannotator/pythonvideoannotator/settings.py b/base/pythonvideoannotator/pythonvideoannotator/settings.py index 04036fd..5c354c5 100644 --- a/base/pythonvideoannotator/pythonvideoannotator/settings.py +++ b/base/pythonvideoannotator/pythonvideoannotator/settings.py @@ -100,4 +100,7 @@ #'Go to the next event and then click the mark the point button.': 'Ctrl+I', #'Select the path of the next object and click the mark the point button.': 'Ctrl+U', #'"Click" the Mark Point button in the current Path.': 'Ctrl++' -} \ No newline at end of file +} + +from AnyQt.QtWidgets import QColorDialog, QFileDialog +PYFORMS_COLORDIALOGS_OPTIONS = QColorDialog.ShowAlphaChannel \ No newline at end of file diff --git a/base/pythonvideoannotator/setup.py b/base/pythonvideoannotator/setup.py index 984b7f6..107bd6d 100644 --- a/base/pythonvideoannotator/setup.py +++ b/base/pythonvideoannotator/setup.py @@ -2,42 +2,44 @@ # -*- coding: utf-8 -*- from setuptools import setup, find_packages -import re +import re, os -with open('pythonvideoannotator/__init__.py', 'r') as fd: + +PACKAGE_PATH = os.path.dirname(os.path.realpath(__file__)) + +with open(os.path.join(PACKAGE_PATH, 'pythonvideoannotator','__init__.py'), 'r') as fd: content = fd.read() version = re.search( r'^__version__\s*=\s*[\'"]([^\'"]*)[\'"]', content, re.MULTILINE).group(1) -with open('../../README.md', 'r') as fd: +with open(os.path.join(PACKAGE_PATH, '..','..','README.md'), 'r') as fd: long_description = fd.read() # REQUIREMENTS BEGIN REQUIREMENTS = [ - "geometry_designer==0.3", - "modular-computer-vision-api-gui==0.2", - "pyforms-gui==4.902", - "modular-computer-vision-api==0.2", - "mcv-gui==0.1", - "python-video-annotator-models-gui==0.6", - "python-video-annotator-models==0.6", - "python-video-annotator-module-timeline==0.5", - "python-video-annotator-module-eventstats==0.4", - "python-video-annotator-module-virtual-object-generator==0.5", - "python-video-annotator-module-deeplab==0.901", - "python-video-annotator-module-contours-images==0.4", - "python-video-annotator-module-tracking==0.5", - "python-video-annotator-module-smooth-paths==0.4", - "python-video-annotator-module-distances==0.4", - "python-video-annotator-module-path-map==0.5", - "python-video-annotator-module-motion-counter==0.4", - "python-video-annotator-module-create-paths==0.4", - "python-video-annotator-module-regions-filter==0.4", - "python-video-annotator-module-import-export==0.4", - "python-video-annotator-module-background-finder==0.4", - "python-video-annotator-module-find-orientation==0.4", - "python-video-annotator-module-path-editor==0.4" + "geometry_designer==0.4.38", + "modular-computer-vision-api-gui==0.3.31", + "pyforms-gui==4.904.152", + "modular-computer-vision-api==0.3.29", + "python-video-annotator-models-gui==0.7.63", + "python-video-annotator-models==0.8.82", + "python-video-annotator-module-timeline==0.6.26", + "python-video-annotator-module-eventstats==0.5.15", + "python-video-annotator-module-virtual-object-generator==0.6.26", + "python-video-annotator-module-deeplab==0.902.21", + "python-video-annotator-module-contours-images==0.5.28", + "python-video-annotator-module-tracking==0.6.38", + "python-video-annotator-module-smooth-paths==0.5.19", + "python-video-annotator-module-distances==0.5.18", + "python-video-annotator-module-path-map==0.6.16", + "python-video-annotator-module-motion-counter==0.5.26", + "python-video-annotator-module-create-paths==0.5.15", + "python-video-annotator-module-regions-filter==0.5.18", + "python-video-annotator-module-import-export==0.5.23", + "python-video-annotator-module-background-finder==0.5.21", + "python-video-annotator-module-find-orientation==0.5.18", + "python-video-annotator-module-path-editor==0.5.28" ] # REQUIREMENTS END diff --git a/docs/source/_static/modules/idtrackerai_1_select_obj.png b/docs/source/_static/modules/idtrackerai_1_select_obj.png index c49fcf9..a3f6cc4 100644 Binary files a/docs/source/_static/modules/idtrackerai_1_select_obj.png and b/docs/source/_static/modules/idtrackerai_1_select_obj.png differ diff --git a/docs/source/index.rst b/docs/source/index.rst index e43ee2d..f822090 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -74,11 +74,12 @@ What is the Python Video Annotator? ------------------------------------ | -| The **PythonVideoAnnotator** is a graphical application written in python, to analyse videos and create notes for events in the video. It was developed with the aim of helping neuroscience and ethology researchers indentify animals' behaviours based on the information extracted from the video. +| The **PythonVideoAnnotator** is a graphical application written in python, to analyze videos and create notes for events in the video. It was developed with the aim of helping neuroscience and ethology researchers identify animals’ behaviors based on the information extracted from the video. | -| Paths, contours and outputs of external devices, like accelerometers, sound recorders, pokes, pressure devices and other sensors can be combined to find classes of events to identify behaviours. +| Paths, contours and outputs of external devices, like accelerometers, sound recorders, pokes, pressure devices and other sensors can be combined to find classes of events to identify behaviors. | + | .. image:: _static/index/project.png diff --git a/docs/source/modules/idtrackerai.rst b/docs/source/modules/idtrackerai.rst index 96eb0e9..2c196ba 100644 --- a/docs/source/modules/idtrackerai.rst +++ b/docs/source/modules/idtrackerai.rst @@ -1,48 +1,151 @@ -=========== -Idtrackerai -=========== +idtracker.ai validator +====================== -This plugin adds functions to correct the tracking and manipulate Idtrackerai projects. -You can visit the project @ `idtracker.ai `_ +This plugin has been developed with the de Polavieja Lab at the Champalimaud Foundation +and it is part of `idtracker.ai `_ project. If you are using +idtracker.ai to track your videos or this plugin to correct trajectories, please cite: -Correct the tracking -____________________ + `Romero-Ferrero, F., Bergomi, M.G., Hinz, R.C., Heras, F.J.H., de Polavieja, G.G., Nature Methods, 2019. + idtracker.ai: tracking all individuals in small or large collectives of unmarked animals `_ -Select the Idtrackerai object in the project tree. +.. code-block:: bibtex + + @article{romero2019idtracker, + title={idtracker.ai: tracking all individuals in small or large collectives of unmarked animals}, + author={Romero-Ferrero, Francisco and Bergomi, Mattia G and Hinz, Robert C and Heras, Francisco JH and de Polavieja, Gonzalo G}, + journal={Nature methods}, + volume={16}, + number={2}, + pages={179}, + year={2019}, + publisher={Nature Publishing Group} + } + +------------------------------------- +A plugin to correct idtracker.ai trajectories +------------------------------------- + +Under good `video condtions ` idtracker.ai typically gives very high accurate trajectories. However, due to not so good video conditions some animals might be badly identified for in some parts of the video. Also, during crossings, the interpolation algorithm might place the centroid of the animal in a place different to the center of mass of the animal. + +This plugin allows to correct wrongly identified animals in the video and also to modify the position of the centroids so that they are closer to the center of mass of the corresponding animal. + +In the following sections we explain how to load a tracking session into the video annotator, how to correct trajectories, and how to save the results to get new and updated trajectories files. + +-------------------------------------- +Load an idtracker.ai tracking session +-------------------------------------- + +If you finished tracking a video using the GUI from `idtracker.ai `_, you can press the **Validate trajectories** button on the bottom right corner to open the validation GUI. The current tracking session will be automatically loaded into the video annotator. Note that depending on the length of the video and the number of animals the process of loading the data can take some time. + +To load an idtracker.ai session from scratch you have two options. Both require to open a terminal (Anaconda Powershell Prompt in Windows) and run a command inside of the virtual environment where you installed idtracker.ai. + +1. Open idtracker.ai by running the command: + +.. code-block:: bash + + idtrackerai + +In the GUI, click the button "Open" and select the video for which you want to validate the trajectories. In the text box "Session", add the name of the session that you want to open. Remember that if the session folder is "session_test", the name of the tracking session will be "test". If the name is correct the button "Validate trajectories" in the bottom right corner will activate. Click that button and the validation GUI will open. + +2. Run the video annotator (see :doc:`../_static/install_and_run/index`), press the button **Open** and open the session folder you want to load. This will automatically read the necessary files from the session folder and create an "Idtrackerai object". + + +-------------------- +Validate the trajectories +-------------------- + +To visualize the trajectories and start validating them, make sure that an "Idtrackerai object" is selected (high-lighted in blue in the "Video list" panel). .. image:: /_static/modules/idtrackerai_1_select_obj.png -On the details section will see the options available to manipulate the tracking. +In the video preview, the centroids of animals that belong to a blob classified by the algorithm as a single animal, will show a number. The centroids of animals that belong to a blob classified by the algorithm as a crossing, will show a number with the prefix 'c-'. The centroids of any animal for which the user modified its identity or the position of the centroid, will show a number with the prefix 'u-'. + +********************************* +Change the identity of a centroid +********************************* + +To change the identity of a centroid, double click on top of a centroid. A window "New identity" will pop up. You can type the new identity and press "Ok". The identity will be propagated to the previous and next frames until the next crossing or until the animal disappears. -**Interpolate trajectories** - You can interpolate trajectories for all the objects IDs or just for a single ID. -To interpolate the trajectory of a single ID you should select the Its centroid first. -**Clear updates** - You can interpolate trajectories of all the objects at the same time or just for a single ID. -To do the interpolation just for a single ID you should select its centroid first. +********************************* +Move a centroid to a different position +********************************* -**Update a centroid ID** - Double click over a centroid and sets the new centroid ID in the window that will popup. +To move a centroid to a different position, click on it, drag it and drop it wherever you want its new position to be. -**Update a centroid position** - Select the centroid and drag it the the new position. +********************************* +Add a new centroid to a blob +********************************* -**Delete centroid** - The button is only available when you select a centroid from a single blob that has multiple centroids associated to it. +To add a new centroid to an existing blob. Click on a centroid of the giving blob. In the "Details" panel on the right, check the box "Add centroid to selected blob" (or press "Ctrl+C"). Then click again on the blob. This will open a window in which you will need to introduce the identity of the centroid to be added. Enter a valid identity and press "Ok". A new centroid will be created. If you see a gray ring in the cursor just click anywhere in the frame and it will disappear. -**Add centroid** - Adds a new centroid to the selected blob. The function is only available if the user selects a blob's centroid. To add a new centroid the user should first check the checkbox "Add centroid" and click in a position of the video. +********************************* +Delete a centroid from a blob +********************************* +To delete a centroid, click on it and press the button "Delete centroid" in the "Details" panel on the right (or press "Ctrl+D"). -Select a centroid -____________________ +Only centroids of duplicated identities and centroids of blobs with multiple centroids can be deleted. To delete a centroid of a unique identity first create a new centroid for that identity. -Click over a centroid of a blob. -.. image:: /_static/modules/idtrackerai_2_select_centroid.png +********************************* +Add a blob +********************************* +Animals that where not detected following the preprocessing parameters won't have a centroid (blob). To assign a centroid to a non-segmented animal, press anywhere in the image where there is not a centroid. In de "Details" panel on the right, check the box "Add blob" (or press "Ctrl+B"). Then double click anywhere in the frame. A window will pop-up where you can introduce the identity of the new centroid generated. Note that blob generated by the user cannot be deleted using any button. They can be cleared using the "Clear user updates" functions as described below. + +********************************* +Clear all user updates +********************************* + +If you want to recover the original identities assigned by the algorithm for a particular part of the video (both centroids and blobs), click on the button "Clear user updates for all identities" in the "Details" panel on the right. This will show a window where you can indicate the starting and ending point to define the interval where the identities will be reset. + + +********************************* +Clear user updates for a given identity +********************************* + +To clear the user updates for a given identity, select a centroid of the identity X that you want to reset. Then, on the "Details" panel on the right, click the button "Clear user updates for X". This will show a window where you can indicate the starting and ending point to define the interval where the identities will be reset. + +********************************* +Local interpolation +********************************* + +In some situations, you might want to modify the position of the centroid for a given identity for multiple frames in a row. This can be very time consuming. To facilitate the work, we implemented a "Local interpolation for X" button. This will interpolate the positions for a given identity between two user generated centroids. Note that this runs a linear interpolation, so we recommend to add user generated centroids when the animal changes direction. + +To interpolate the positions for a given identity follow these steps. + +1. Modify the centroid of a given identity for a set of frames. You do not need to modify it for all the frame, just when the animals is changing direction. +2. Make sure that the identity is unique for the interval where you want to interpolate the centroids. +3. Click the button "Local interpolation for X". +4. Add the initial and ending frames of the interval where you want the interplation to run. Note that the first and last frame must include a user generated centroid (i.e. a centroid with the prefix 'u-'). + + +********************************* +Global interpolation +********************************* + +Click the button "Global interpolation" to run the idtracker.ai interpolation algorithm that assigns the centroids to the blobs that correspond to multiple animals. This is particularly useful when you are only modifying identities before and after crosings. The algorithm might work if you have also modified the positions the centroids in the blobs corresponding to crossings. However, we haven't test it deeply, so we recommend to only used if you only modified identities and not centroids. + +-------------------- +Save the results +-------------------- + +To save the results of your validation, press the button "Save updated identities" on the "Details" pannel. This will update the "blobs_collection_no_gaps.npy" file in the preprocessing folder insider of the session folder. Also it will generate two new "trajectories_TIMESTAMP.npy" and "trajectories_wo_gaps_TIMESTAMP.npy" files in the folders "trajectories" and "trajectories_wo_gaps" respectively. Note that this proces can take a few minutes if your video is very long or it has many animals. We recommend saving the updated identities regularly. + + +----------- Keys events -____________ +----------- + +A part form the :doc:`../user-docs/shortcuts/index` of the video annotator, we added two new shortcuts to automatically advance to the next and previous crossings (or frames where an animal is missing). ========================================================================== ================================= EVENT SHORT KEYS ========================================================================== ================================= -Go to the next crossing. Ctrl+M -Go to the previous crossing. Ctrl+N +Go to next crossing Ctrl+S +Go to previous crossing Ctrl+A +Check/Uncheck add centroid Ctrl+C +Check/Uncheck add blob Ctrl+B +Delete centroid Ctrl+D ========================================================================== ================================= - diff --git a/libraries/confapp b/libraries/confapp index 862feaf..a1356ee 160000 --- a/libraries/confapp +++ b/libraries/confapp @@ -1 +1 @@ -Subproject commit 862feaf142cc699ceee79466546ebda987554080 +Subproject commit a1356ee118430f79e4ec6ae21625de924d7045c8 diff --git a/libraries/geometry-designer b/libraries/geometry-designer index 9d74aae..c040c0e 160000 --- a/libraries/geometry-designer +++ b/libraries/geometry-designer @@ -1 +1 @@ -Subproject commit 9d74aae615d612a289b398812e693b29d985e460 +Subproject commit c040c0e9ca4ef1d17b26453f01958a640001c321 diff --git a/libraries/mcv-api b/libraries/mcv-api index 38ed39b..b4e2e85 160000 --- a/libraries/mcv-api +++ b/libraries/mcv-api @@ -1 +1 @@ -Subproject commit 38ed39bc19ef141c2d3eb0f731c5b89739da4774 +Subproject commit b4e2e8580fa2383de2cd9e18f5610cd48adf3f85 diff --git a/libraries/mcv-gui b/libraries/mcv-gui index 4464500..01ba1aa 160000 --- a/libraries/mcv-gui +++ b/libraries/mcv-gui @@ -1 +1 @@ -Subproject commit 446450089eefef8bd6f4b2de2f109a3f22e99b18 +Subproject commit 01ba1aa039c2ba88b8f9540056193ad34e400425 diff --git a/libraries/mcv-gui-editor b/libraries/mcv-gui-editor deleted file mode 160000 index ddd626a..0000000 --- a/libraries/mcv-gui-editor +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ddd626afa16a713b1e4fe2d4b9d6ae46369b5d01 diff --git a/libraries/pyforms-gui b/libraries/pyforms-gui index 40149a6..5bb69b4 160000 --- a/libraries/pyforms-gui +++ b/libraries/pyforms-gui @@ -1 +1 @@ -Subproject commit 40149a63f6f0fb3b986f171c3d9d758d9cd6e82a +Subproject commit 5bb69b4f9ec5695f507d5f9accc7884d6f0d3b82 diff --git a/plugins/pythonvideoannotator-module-backgroundfinder b/plugins/pythonvideoannotator-module-backgroundfinder index 907820f..1186cd8 160000 --- a/plugins/pythonvideoannotator-module-backgroundfinder +++ b/plugins/pythonvideoannotator-module-backgroundfinder @@ -1 +1 @@ -Subproject commit 907820f2a2931b053ca1094d995d24dfc5e887e1 +Subproject commit 1186cd877a7d459a075764adff2bcea97716d1ba diff --git a/plugins/pythonvideoannotator-module-contoursimages b/plugins/pythonvideoannotator-module-contoursimages index 22d1d61..dd419ce 160000 --- a/plugins/pythonvideoannotator-module-contoursimages +++ b/plugins/pythonvideoannotator-module-contoursimages @@ -1 +1 @@ -Subproject commit 22d1d61c9ddafd596e23f7bac648366c6a101957 +Subproject commit dd419ce7794fcfe368f1098be84ebf03584ab232 diff --git a/plugins/pythonvideoannotator-module-createpaths b/plugins/pythonvideoannotator-module-createpaths index 82f37c2..d6ab5d7 160000 --- a/plugins/pythonvideoannotator-module-createpaths +++ b/plugins/pythonvideoannotator-module-createpaths @@ -1 +1 @@ -Subproject commit 82f37c28cc4a17feb96b28e20f03119f44f08a01 +Subproject commit d6ab5d7bd3d9ec98585b5658fd475c0a92ff98f8 diff --git a/plugins/pythonvideoannotator-module-deeplab b/plugins/pythonvideoannotator-module-deeplab index 968460c..fa6c315 160000 --- a/plugins/pythonvideoannotator-module-deeplab +++ b/plugins/pythonvideoannotator-module-deeplab @@ -1 +1 @@ -Subproject commit 968460c2fbd3ec84c27f695465f092ce57448a40 +Subproject commit fa6c3156ccc38fe1d6737d3b3fdef10adf832edf diff --git a/plugins/pythonvideoannotator-module-distances b/plugins/pythonvideoannotator-module-distances index 81c5a37..f6c4afb 160000 --- a/plugins/pythonvideoannotator-module-distances +++ b/plugins/pythonvideoannotator-module-distances @@ -1 +1 @@ -Subproject commit 81c5a37e8021989a1ada382fe1b7ace3e5f1e3c5 +Subproject commit f6c4afb89d4eac5c70602f349422046d757e4ac8 diff --git a/plugins/pythonvideoannotator-module-eventsstats b/plugins/pythonvideoannotator-module-eventsstats index 00fd89d..e2dc5ee 160000 --- a/plugins/pythonvideoannotator-module-eventsstats +++ b/plugins/pythonvideoannotator-module-eventsstats @@ -1 +1 @@ -Subproject commit 00fd89d8f34bcac89dbaaefb3e9b21b19c132cb8 +Subproject commit e2dc5ee50f3d2a36c9cb8b81202e318022b35650 diff --git a/plugins/pythonvideoannotator-module-findorientation b/plugins/pythonvideoannotator-module-findorientation index 58faa7a..3e94c06 160000 --- a/plugins/pythonvideoannotator-module-findorientation +++ b/plugins/pythonvideoannotator-module-findorientation @@ -1 +1 @@ -Subproject commit 58faa7afb61d9bbbfd418c44649ab945992367da +Subproject commit 3e94c06ebf8466eb9e39ab35ae4556930ee11380 diff --git a/plugins/pythonvideoannotator-module-idtrackerai b/plugins/pythonvideoannotator-module-idtrackerai index f0868a8..9e46a5d 160000 --- a/plugins/pythonvideoannotator-module-idtrackerai +++ b/plugins/pythonvideoannotator-module-idtrackerai @@ -1 +1 @@ -Subproject commit f0868a843235629f58bda6d8c7418e643cfcd917 +Subproject commit 9e46a5db723a86beaa5e04c1653a3dd1e6672e36 diff --git a/plugins/pythonvideoannotator-module-importexport b/plugins/pythonvideoannotator-module-importexport index 4df5fc1..eaca485 160000 --- a/plugins/pythonvideoannotator-module-importexport +++ b/plugins/pythonvideoannotator-module-importexport @@ -1 +1 @@ -Subproject commit 4df5fc198e238e787e6e02cceebd2691224d5227 +Subproject commit eaca48576daa482eab0576a7f8ad7da17ab51725 diff --git a/plugins/pythonvideoannotator-module-motioncounter b/plugins/pythonvideoannotator-module-motioncounter index 5db12cc..0fe282d 160000 --- a/plugins/pythonvideoannotator-module-motioncounter +++ b/plugins/pythonvideoannotator-module-motioncounter @@ -1 +1 @@ -Subproject commit 5db12ccf60efa4d3deded339fee286fb74d61b81 +Subproject commit 0fe282d202ccf88b2d74d8153b80170ce69d3dc4 diff --git a/plugins/pythonvideoannotator-module-patheditor b/plugins/pythonvideoannotator-module-patheditor index 29d57af..31612ea 160000 --- a/plugins/pythonvideoannotator-module-patheditor +++ b/plugins/pythonvideoannotator-module-patheditor @@ -1 +1 @@ -Subproject commit 29d57af1548e552e390d94353f29b06518af15e9 +Subproject commit 31612ea9620c2c247c22c55a93fb13f8a0834691 diff --git a/plugins/pythonvideoannotator-module-pathmap b/plugins/pythonvideoannotator-module-pathmap index ec3f8a7..623ee14 160000 --- a/plugins/pythonvideoannotator-module-pathmap +++ b/plugins/pythonvideoannotator-module-pathmap @@ -1 +1 @@ -Subproject commit ec3f8a7dcf5f94902503b34f852b05e76475b004 +Subproject commit 623ee143ea1a676738c558e2ae5da4be5ed1f9eb diff --git a/plugins/pythonvideoannotator-module-regionsfilter b/plugins/pythonvideoannotator-module-regionsfilter index d9eaf4b..5ae9e34 160000 --- a/plugins/pythonvideoannotator-module-regionsfilter +++ b/plugins/pythonvideoannotator-module-regionsfilter @@ -1 +1 @@ -Subproject commit d9eaf4b7bf976999bbf34b9a635c81b80be634ad +Subproject commit 5ae9e3462f09a47effaebaa329434dd19afb559a diff --git a/plugins/pythonvideoannotator-module-smoothpaths b/plugins/pythonvideoannotator-module-smoothpaths index 5b9e5b8..f5fc615 160000 --- a/plugins/pythonvideoannotator-module-smoothpaths +++ b/plugins/pythonvideoannotator-module-smoothpaths @@ -1 +1 @@ -Subproject commit 5b9e5b84c2d19455d7e61d4279216d49a9bbe88a +Subproject commit f5fc615a7b030beb17f4df50eb590e170a6ba0dc diff --git a/plugins/pythonvideoannotator-module-timeline b/plugins/pythonvideoannotator-module-timeline index ce22484..d197d94 160000 --- a/plugins/pythonvideoannotator-module-timeline +++ b/plugins/pythonvideoannotator-module-timeline @@ -1 +1 @@ -Subproject commit ce22484213665eaba621760213ee553c49d593ec +Subproject commit d197d94f4a72b70704d0a8e7e1ed4cf8da078f35 diff --git a/plugins/pythonvideoannotator-module-tracking b/plugins/pythonvideoannotator-module-tracking index 3d6ebdf..dfca3f7 160000 --- a/plugins/pythonvideoannotator-module-tracking +++ b/plugins/pythonvideoannotator-module-tracking @@ -1 +1 @@ -Subproject commit 3d6ebdfa0acd921fefb4d3f20c60035b62fe5958 +Subproject commit dfca3f7e8af653de092c2fc204bf223cfc8259e8 diff --git a/plugins/pythonvideoannotator-module-virtualobjectgenerator b/plugins/pythonvideoannotator-module-virtualobjectgenerator index bc81a67..d2fd9b5 160000 --- a/plugins/pythonvideoannotator-module-virtualobjectgenerator +++ b/plugins/pythonvideoannotator-module-virtualobjectgenerator @@ -1 +1 @@ -Subproject commit bc81a676f4e9969745e8227e20cdf613429c28c1 +Subproject commit d2fd9b56b206b7531610f01bfeacb1b498cd7056 diff --git a/utils/deploy-pypi.py b/utils/deploy-pypi.py index 306e47b..ba24356 100644 --- a/utils/deploy-pypi.py +++ b/utils/deploy-pypi.py @@ -1,57 +1,110 @@ -import os +import os, shutil import xmlrpc.client from subprocess import Popen, PIPE -import shutil - +from setuptools import find_packages +from natsort import natsorted + +###### CONFIGURATIONS ############################# +HEADER = '\033[95m' +OKBLUE = '\033[94m' +OKGREEN = '\033[92m' +WARNING = '\033[93m' +FAIL = '\033[91m' +ENDC = '\033[0m' +BOLD = '\033[1m' +UNDERLINE = '\033[4m' + +DEBUG = False +DEPLOY = True + +if DEBUG: + PYPI_URL = 'https://test.pypi.org' +else: + PYPI_URL = 'https://pypi.org' + +# Dictionary with the correspondence of the libraries and folders. +PACKAGES = { 'pyforms-gui': 'pyforms_gui' } +PACKAGES_TO_IGNORE = [ + 'confapp' +] -pypi = xmlrpc.client.ServerProxy('https://pypi.org') +PACKAGES_TO_IGNORE_FOR_REQUIREMENTS = [ + 'confapp', + 'python-video-annotator-module-idtrackerai' +] -MAIN_NAME = 'pythonvideoannotator' -MAIN_PATH = os.path.join('base', MAIN_NAME) -MAIN_REPO = 'python-video-annotator' +# sub packages directories to look for updates DIRECTORIES_TO_SEARCH_FORM = [ os.path.join('libraries'), os.path.join('base'), os.path.join('plugins'), ] -CURRENT_DIRECTORY = os.getcwd() +MAIN_NAME = 'pythonvideoannotator' # main package name +MAIN_PATH = os.path.join('base', MAIN_NAME) # main package path +MAIN_REPO = 'python-video-annotator' # name of the main package on pypi +APP_DIRECTORY = os.getcwd() # current directory -Popen(['pip','install','--upgrade','setuptools','wheel','twine']) +#################################################### + +pypi = xmlrpc.client.ServerProxy(PYPI_URL) + +# make sure all the packages required to deploy to pypi are installed +Popen(['pip','install','--upgrade','setuptools','wheel','twine']).communicate() def version_compare(a, b): - try: - a = float(a) - b = float(b) - except: - return -1 """ - a = a.split('.') - b = b.split('.') - for a_value, b_value in zip(a, b): - a_value = int(a_value) - b_value = int(b_value) - - if a_value>b_value: - return -1 - elif a_valuelen(b): - return -1 - elif len(a)b, returns -1 if b>a + """ + if a == b: return 0 + versions = natsorted([a, b]) + if a==versions[-1]: return -1 + if b==versions[-1]: return 1 + raise Exception('Error when comparing versions') + + + +def update_package_version(package_name, setup_path, new_version): + """ + Update the version of the package + + :param str package_name: Package name. + :param str setup_path: Path of the setup.py file. + :param str new_version: The new version to update. + :return: """ - if a==b: return 0 - if ab: return -1 + if package_name in PACKAGES: + package = PACKAGES[package_name] + else: + packages = find_packages(where=setup_path) + package = packages[0] + + package_path = os.path.join(setup_path, package) + init_path = os.path.join(package_path, '__init__.py') + + with open(init_path) as infile: text = infile.read() + try: + begin = text.index('__version__') + end = text.index('\n', begin) + text = text.replace( text[begin:end], f'__version__ = "{new_version}"') + except ValueError: + text = text + f'\n__version__ = "{new_version}"' + + with open(init_path, 'w') as outfile: outfile.write(text) + + def check_version_and_upload(dir_path): + """ + Check the package version and decide if should be updated or not. + :param str dir_path: Path of the package. + """ os.chdir(dir_path) try: @@ -67,45 +120,79 @@ def check_version_and_upload(dir_path): except Exception as e: print(e) - - - version = Popen(["python", 'setup.py', '--version'], stdout=PIPE).stdout.read() - version = version.strip().decode() + local_version = Popen(["python", 'setup.py', '--version'], stdout=PIPE).stdout.read() + local_version = local_version.strip().decode().strip() package_name = Popen(["python", 'setup.py', '--name'], stdout=PIPE).stdout.read() package_name = package_name.strip().decode().replace(' ', '-') package_name = package_name.replace('---', '-').lower() - remote_version = pypi.package_releases(package_name) + if package_name in PACKAGES_TO_IGNORE: + os.chdir(APP_DIRECTORY) + return False, package_name, local_version + tmp = pypi.package_releases(package_name) + remote_version = tmp[0] if tmp else 'None' - print( - "{:<65} {:<10} {:<10}".format(package_name, version, remote_version[0] if remote_version else 'None') - ) + tagged_version = Popen(["git", "describe", "--tags"], stdout=PIPE).stdout.read() + tagged_version = tagged_version.strip().decode().split('-') + tagged_version = tagged_version[0] + + print(f"{OKGREEN}{package_name:<65} {local_version:<25} {tagged_version:<25} {remote_version:<25}{ENDC}") + + #git_tag = Popen(["git", 'tag'], stdout=PIPE).stdout.read() + #if git_tag == f'v{new_version}': + # return updated = False - if len(remote_version) == 0 or version_compare(version, remote_version[0]) < 0: - print('----- UPLOADING PYPI -----', package_name) + if remote_version=='None' or version_compare(tagged_version, remote_version) < 0: + print(OKBLUE+f'\tUPLOADING TO PYPI\t\t[{package_name}]', ENDC) + + update_package_version(package_name, dir_path, tagged_version) if os.path.isdir('./dist'): shutil.rmtree('./dist') + Popen(['python', 'setup.py', 'sdist', 'bdist_wheel'], stdout=PIPE).communicate() - Popen(['twine', 'upload', os.path.join('dist','*')]).communicate() + + ###################################################################################### + # DEPLOY TO PYPI ##################################################################### + ###################################################################################### + if DEPLOY: + if not DEBUG: + Popen(['twine', 'upload', os.path.join('dist','*')]).communicate() + else: + Popen(['twine', 'upload', '--repository', 'pypitest', os.path.join('dist', '*'), '--verbose']).communicate() + ###################################################################################### + + """ + remote_version = pypi.package_releases(package_name) + if version_compare(new_version, remote_version[0])==0: + Popen(['git', 'add', '--all']).communicate() + Popen(['git', 'commit', '-m', '"upload to pypi"']).communicate() + Popen(['git', 'tag', '-a', f'v{new_version}', '-m', 'generated with deploy-pypi.py script']).communicate() + """ updated = True - os.chdir(CURRENT_DIRECTORY) + os.chdir(APP_DIRECTORY) - return updated, package_name, version + remote_version = pypi.package_releases(package_name) + remote_version_str = remote_version[0] if remote_version else 'None' + return updated, package_name, tagged_version -requirements = [] -should_update = False +# List of requirements +requirements = [] for search_dir in DIRECTORIES_TO_SEARCH_FORM: + print( + BOLD+HEADER+"\n{:<65} {:<25} {:<25} {:<25}".format('PACKAGE', 'LOCAL', 'TAGGED VERSION', 'REMOTE')+ENDC + ) + for dir_name in os.listdir(search_dir): - dir_path = os.path.abspath(os.path.join(search_dir, dir_name)) + dir_path = os.path.abspath(os.path.join(search_dir, dir_name)) # is not a directory or is the main repository if not os.path.isdir(dir_path) or MAIN_NAME==dir_name: continue @@ -115,44 +202,22 @@ def check_version_and_upload(dir_path): updated, package_name, version = check_version_and_upload(dir_path) - if updated: - should_update = True - - if package_name != MAIN_REPO: + if package_name != MAIN_REPO and package_name not in PACKAGES_TO_IGNORE_FOR_REQUIREMENTS: requirements.append("{module}=={version}".format(module=package_name, version=version)) -with open( os.path.join(MAIN_PATH, 'setup.py') ) as infile: - text = infile.read() - -begin = text.index('# REQUIREMENTS BEGIN') -end = text.index('# REQUIREMENTS END', begin)+len('# REQUIREMENTS END') +#### UPDATE REQUIREMENTS IN THE MAIN SETUP.PY ################## +with open( os.path.join(MAIN_PATH, 'setup.py') ) as infile: text = infile.read() +begin = text.index('# REQUIREMENTS BEGIN') +end = text.index('# REQUIREMENTS END', begin)+len('# REQUIREMENTS END') new_text = """# REQUIREMENTS BEGIN REQUIREMENTS = [ "{}" ] # REQUIREMENTS END""".format('",\n\t"'.join(requirements)) - text = text.replace(text[begin:end], new_text) +with open( os.path.join(MAIN_PATH, 'setup.py'), 'w' ) as outfile: outfile.write(text) +#### END UPDATE REQUIREMENTS ################################### -with open( os.path.join(MAIN_PATH, 'setup.py'), 'w' ) as outfile: - outfile.write(text) - -with open( os.path.join(MAIN_PATH, MAIN_NAME, '__init__.py') ) as infile: - text = infile.read() - -if should_update: - os.chdir(MAIN_PATH) - version = Popen(["python", 'setup.py', '--version'], stdout=PIPE).stdout.read() - version = float(version.strip().decode()) - os.chdir(CURRENT_DIRECTORY) - - begin = text.index('__version__') - end = text.index('\n', begin) - text = text.replace(text[begin:end], '__version__ = "{0}"'.format(round(version + 0.001, 3))) - -with open( os.path.join(MAIN_PATH, MAIN_NAME, '__init__.py'), 'w' ) as outfile: - outfile.write(text) - - -updated, package_name, version = check_version_and_upload(MAIN_PATH) \ No newline at end of file +#### UPDATE THE MAIN PACKAGE ################## +updated, package_name, version = check_version_and_upload(os.path.abspath(MAIN_PATH)) \ No newline at end of file