/*========================================================================= medInria Copyright (c) INRIA 2013 - 2023. All rights reserved. See LICENSE.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. =========================================================================*/ #pragma once #include #include #include class Authenticator; class RequestManager; class LocalInfo; class SyncNetwork; class AsyncNetwork; /** * @class medShanoir * @author Léo Filoche, Florent Leray * @brief The medShanoir class is a medAbstractSource that allows to connect to a Shanoir NG server. * The class is based on the Shanoir API. See more at https://github.com/fli-iam/shanoir-ng * @details * This class is used as an interface between medInria and the plugin's internal logic. It does not contain any logic by itself. */ class medShanoir : public medAbstractSource { Q_OBJECT public: /** * @brief medShanoir constructor * initializes the private members of the class, and connects their signals and slots. */ medShanoir(); /** * @brief medShanoir destructor * deletes properly the private members of the class. * @details * Not used for now, because the members are deleted by the parent class. */ virtual ~medShanoir(); /* ***********************************************************************/ /* *************** Init/set/ctrl source properties ***********************/ /* ***********************************************************************/ /** * sets up the instance id if pi_instanceId is valid * @param pi_instanceId an instance id. * @return the success of the update operation. */ bool initialization(QString const &pi_instanceId) override; /** * sets up the instance name if pi_instanceName is valid * @param pi_instanceName an instance name * @return the success of the update operation. */ bool setInstanceName(QString const &pi_instanceName) override; /** * @param pi_Enable indicates whether the method connects or disconnects * @return the success of the operation */ bool connect(bool pi_bEnable = true) override; /** * @return all the medAbstractParameter that are used by the source. */ QList getAllParameters() override; /** * @return the medAbstractParameter that need to be ciphered by the application. */ QList getCipherParameters() override; /** * @return the medAbstractParameter that are volatil (their value are not saved by the app). */ QList getVolatilParameters() override; /** * @return the medAbstractParameter that can be used to filter the data. */ QList getFilteringParameters() override; /* ***********************************************************************/ /* *************** Get source properties *********************************/ /* ***********************************************************************/ /** * @return whether the source is writable or not. (false) */ bool isWritable() override; /** * @return whether the source is local or not. (false) */ bool isLocal() override; /** * @return whether the source is cached or not. (false) */ bool isCached() override; /** * @return whether the plugin instance is connected to the server or not. */ bool isOnline() override; /** * @return whether the plugin fetches data by minimal entries or mandatory attributes. (true) */ bool isFetchByMinimalEntriesOrMandatoryAttributes() override; /** * @return the IO interface of the source. (IO_FILE) */ int getIOInterface() override; /** * @return a map that links the type of the data to the format of the data that can be read by the source. (here, only "Image" -> ".nii.gz") */ QMap getTypeAndFormat() override; /* ***********************************************************************/ /* *************** Get source structure information **********************/ /* ***********************************************************************/ /** * @return the name of the plugin instance. It is set up by setInstanceName(QString) */ QString getInstanceName() override; /** * @return the id of the plugin instance. It is set up by initialization(QString) */ QString getInstanceId() override; /** * @return the number of tree-view levels of the source. (7) */ unsigned int getLevelCount() override; /** * @return the default writable level of the source. (7) * @details it is important to note that users with lower privileges will not be able to write on the server. */ unsigned int getLevelDesiredWritable() override; /** * @return the names of the levels of the source. ({"study", "subject", "examination", "dataset-acquisition", "dataset", "processingDataset", "processedDataset"}) */ QStringList getLevelNames() override; /** * @param pi_uiLevel id of a level * @return the name of the pi_uiLevel */ QString getLevelName(unsigned int pi_uiLevel) override; /** * @param pi_uiLevel id of a level * @return whether the level is writable or not. * @details it is important to note that users with lower privileges will not be able to write on the server. */ bool isLevelWritable(unsigned int pi_uiLevel) override; /** * @param pi_uiLevel id of a level * @return the mandatory attributes of the level. * @details for now, the mandatory attributes are the same as the minimal entries : * "name", "type" &"format" */ QStringList getMandatoryAttributesKeys(unsigned int pi_uiLevel) override; /* ***********************************************************************/ /* *************** Get elements data *************************************/ /* ***********************************************************************/ /** * @param pi_uiLevel id of a level * @param parentKey the key of a tree-view element * @return the corresponding minimal entries (children) that are contained in the element of the level. * @details the system of keys is used to identify the elements in the tree-view. Each level is identified by its id (an integer), and the key is a concatenation of the ids of the parents, separated by a dot. For instance, we a use key of the form studyId.subjectId.examinationId in order to designate an examination. */ QList getMinimalEntries(unsigned int pi_uiLevel, QString parentKey) override; /** * same goal as getMinimalEntries(), except that levelMinimalEntries are in the form of a QMap, and that other information can be added (date, owner, etc) * @param i_uiLevel a tree-view level id * @param parentKey the key of a tree-view element * @return the corresponding mandatory attributes of the element that are contained inside the level. * @details for now, the mandatory attributes are the same as the minimal entries. */ QList> getMandatoryAttributes(unsigned int pi_uiLevel, QString parentKey) override; /** * has no effect for now. (returns false) */ bool getAdditionalAttributes(unsigned int pi_uiLevel, QString key, datasetAttributes &po_attributes) override; /* ***********************************************************************/ /* *************** Get data *************************************/ /* ***********************************************************************/ /** * @param pi_uiLevel tree-view level id * @param key the key of a tree-view element * @return the data of the element that is contained inside the level. (it can be empty if the element is a folder) * @details this function is only useful for the datasets levels ("real" datasets and processed datasets - id 4 & 6). In those cases, it returns the path to the Nifti file that is contained in the dataset. * The Nifti file is downloaded as a zip from the server, decompressed and stored in a temporary folder, that is deleted in reasonnable time after the function is called, or when the application is closed. */ QVariant getDirectData(unsigned int pi_uiLevel, QString key) override; /** * asynchronous version of getDirectData() * @param pi_uiLevel tree-view level id . * @param key the key of a tree-view element * @return id of the request */ int getAssyncData(unsigned int pi_uiLevel, QString key) override; /* ***********************************************************************/ /* *************** Store data ***********************************/ /* ***********************************************************************/ /** * @param data a path to a Nifti file. * @param pio_minimalEntries the minimal entries of the element to store. * @param pi_uiLevel tree-view level id . * @param parentKey the key of a tree-view element * @return whether the operation was successful or not. * @details this function is only useful for the datasets levels ("real" datasets and processed datasets - id 4 & 6). In those cases, it stores the path to the Nifti file that is contained in the dataset. * The Nifti file is uploaded as a zip to the server, compressed and stored in a temporary folder, that is deleted in reasonnable time after the function is called, or when the application is closed. */ bool addDirectData(QVariant data, levelMinimalEntries &pio_minimalEntries, unsigned int pi_uiLevel, QString parentKey) override; /** * asynchronous version of addDirectData() * @param data a path to a Nifti file. * @param pio_minimalEntries the minimal entries of the element to store. * @param pi_uiLevel tree-view level id . * @param parentKey the key of a tree-view element * @return id of the request */ int addAssyncData(QVariant data, levelMinimalEntries &pio_minimalEntries, unsigned int pi_uiLevel, QString parentKey) override; /** * has no effect for now. (returns false) */ bool createPath(QList &pio_path, datasetAttributes const &pi_attributes, unsigned int pi_uiLevel = 0, QString parentKey = "") override; /** * @param pio_minimalEntries the minimal entries of the element to store. * @param pi_attributes the attributes of the element to store. -- they are not used for now. * @param pi_uiLevel tree-view level id . * @param parentKey the key of a tree-view element * @return whether the operation was successful or not. * @details this function is only useful for the creation of processing datasets (id 5). */ bool createFolder(levelMinimalEntries &pio_minimalEntries, datasetAttributes const &pi_attributes, unsigned int pi_uiLevel, QString parentKey) override; /** * has no effect for now. (returns false) */ bool alterMetaData(datasetAttributes const &pi_attributes, unsigned int pi_uiLevel, QString key) override; /** * has no effect for now. (returns false) */ bool getThumbnail(QPixmap &po_thumbnail, unsigned int pi_uiLevel, QString key) override; /** * has no effect for now. (returns false) */ bool setThumbnail(QPixmap &pi_thumbnail, unsigned int pi_uiLevel, QString key) override; /** * has no effect for now. (returns false) * @details the plugin is not caching anything for now, therefore this function is not used. */ bool commitData(QVariant data, levelMinimalEntries &pio_minimalEntries, unsigned int pi_uiLevel, QString parentKey) override; /** * has no effect for now. (returns false) * @details the plugin is not caching anything for now, therefore this function is not used. */ int push(unsigned int pi_uiLevel, QString key) override; /* ***********************************************************************/ /* *************** Handle async results ********************************/ /* ***********************************************************************/ /** * @param pi_iRequest id of a request * @return the results of the request if it exists and is finished. An empty QVariant otherwise. * @details gets the results of an asynchronous request if it exists and is finished. */ QVariant getAsyncResults(int pi_iRequest) override; /* ***********************************************************************/ /* *************** Optional functions ***********************************/ /* ***********************************************************************/ /** * has no effect for now. (returns false) */ inline medAbstractWritingPolicy *getWritingPolicy() { return nullptr; } public slots: /** * @param pi_iRequest id of a request * @details aborts an asynchronous request if it exists and is not finished. */ void abort(int pi_iRequest) override; private: //members LocalInfo * m_info; //for the plugin's general information & instance management Authenticator * m_authent; //for authentication to the shanoir server SyncNetwork * m_syncNet; //for synchronous requests --managing the treeview structure, getting & adding data synchronously AsyncNetwork * m_asyncNet; //for asynchronous requests --getting & adding data aysnchronously RequestManager * m_requester; //for network requests --is used by Authentificator, SyncNetwork & AsyncNetwork };