Example #1
0
    def list_users(self):
        """Get a list of user(s) involved in a project."""
        # Get user list from API
        try:
            response = requests.get(
                DDSEndpoint.LIST_PROJ_USERS,
                headers=self.token,
                params={"project": self.project},
                timeout=DDSEndpoint.TIMEOUT,
            )
        except requests.exceptions.RequestException as err:
            raise exceptions.ApiRequestError(
                message=(
                    "Failed to get list of users"
                    + (
                        ": The database seems to be down."
                        if isinstance(err, requests.exceptions.ConnectionError)
                        else "."
                    )
                )
            )

        # Check resposne
        if not response.ok:
            raise exceptions.APIError(f"Failed to get any users: {response.text}")

        # Get result from API
        try:
            resp_json = response.json()
        except simplejson.JSONDecodeError as err:
            raise exceptions.APIError(f"Could not decode JSON response: {err}")

        research_users = resp_json.get("research_users")

        # Print users
        if not self.json:
            self.__print_users_table(research_users)

        return research_users
Example #2
0
    def update_status(self, new_status, deadline=None, is_aborted=False, no_mail=False):
        """Update project status"""

        extra_params = {"new_status": new_status, "send_email": not no_mail}
        if deadline:
            extra_params["deadline"] = deadline
        if is_aborted:
            extra_params["is_aborted"] = is_aborted
        try:
            response = requests.post(
                DDSEndpoint.UPDATE_PROJ_STATUS,
                headers=self.token,
                params={"project": self.project},
                json=extra_params,
                timeout=DDSEndpoint.TIMEOUT,
            )
        except requests.exceptions.RequestException as err:
            raise exceptions.ApiRequestError(
                message=(
                    "Failed to update project status"
                    + (
                        ": The database seems to be down."
                        if isinstance(err, requests.exceptions.ConnectionError)
                        else "."
                    )
                )
            )

        # Check response
        if not response.ok:
            raise exceptions.APIError(f"An Error occured: {response.json().get('message')}")

        # Get result from API
        try:
            resp_json = response.json()
        except simplejson.JSONDecodeError as err:
            raise exceptions.APIError(f"Could not decode JSON response: {err}")
        else:
            dds_cli.utils.console.print(f"Project {resp_json.get('message')}")
Example #3
0
        def __api_call_list_files(folder: str):
            # Make call to API
            try:
                resp_json = requests.get(
                    DDSEndpoint.LIST_FILES,
                    params={"project": self.project},
                    json={"subpath": folder, "show_size": show_size},
                    headers=self.token,
                    timeout=DDSEndpoint.TIMEOUT,
                )
            except requests.exceptions.RequestException as err:
                raise exceptions.APIError(f"Problem with database response: '{err}'")

            resp_json = resp_json.json()

            if not "files_folders" in resp_json:
                raise exceptions.NoDataError(f"Could not find folder: '{folder}'")

            sorted_files_folders = sorted(resp_json["files_folders"], key=lambda f: f["name"])

            if not sorted_files_folders:
                raise exceptions.NoDataError(f"Could not find folder: '{folder}'")

            return sorted_files_folders
Example #4
0
    def list_projects(self, sort_by="Updated"):
        """Get a list of project(s) the user is involved in."""
        # Get projects from API
        try:
            response = requests.get(
                DDSEndpoint.LIST_PROJ,
                headers=self.token,
                json={"usage": self.show_usage},
                timeout=DDSEndpoint.TIMEOUT,
            )
        except requests.exceptions.RequestException as err:
            raise exceptions.ApiRequestError(
                message=(
                    "Failed to get list of projects"
                    + (
                        ": The database seems to be down."
                        if isinstance(err, requests.exceptions.ConnectionError)
                        else "."
                    )
                )
            )

        # Check response
        if not response.ok:
            raise exceptions.APIError(f"Failed to get any projects: {response.text}")

        # Get result from API
        try:
            resp_json = response.json()
        except simplejson.JSONDecodeError as err:
            raise exceptions.APIError(f"Could not decode JSON response: {err}")

        # Cancel if user not involved in any projects
        usage_info = resp_json.get("total_usage")
        total_size = resp_json.get("total_size")
        project_info = resp_json.get("project_info")
        always_show = resp_json.get("always_show", False)
        if not project_info:
            raise exceptions.NoDataError("No project info was retrieved. No files to list.")

        for project in project_info:
            try:
                last_updated = pytz.timezone("UTC").localize(
                    datetime.datetime.strptime(project["Last updated"], "%a, %d %b %Y %H:%M:%S GMT")
                )
            except ValueError as err:
                raise exceptions.ApiResponseError(
                    f"Time zone mismatch: Incorrect zone '{project['Last updated'].split()[-1]}'"
                )
            else:
                project["Last updated"] = last_updated.astimezone(tzlocal.get_localzone()).strftime(
                    "%a, %d %b %Y %H:%M:%S %Z"
                )

        # Sort projects according to chosen or default, first ID
        sorted_projects = self.__sort_projects(projects=project_info, sort_by=sort_by)

        if not self.json:
            self.__print_project_table(sorted_projects, usage_info, total_size, always_show)

        # Return the list of projects
        return sorted_projects
Example #5
0
    def list_files(self, folder: str = None, show_size: bool = False):
        """Create a tree displaying the files within the project."""
        LOG.info(f"Listing files for project '{self.project}'")
        if folder:
            LOG.info(f"Showing files in folder '{escape(folder)}'")

        if folder is None:
            folder = ""
        # Make call to API
        try:
            response = requests.get(
                DDSEndpoint.LIST_FILES,
                params={"project": self.project},
                json={"subpath": folder, "show_size": show_size},
                headers=self.token,
                timeout=DDSEndpoint.TIMEOUT,
            )
        except requests.exceptions.RequestException as err:
            raise exceptions.APIError(
                message=(
                    f"Failed to get list of files in project '{self.project}'"
                    + (
                        ": The database seems to be down."
                        if isinstance(err, requests.exceptions.ConnectionError)
                        else "."
                    )
                )
            )

        if not response.ok:
            raise exceptions.APIError(f"Failed to get list of files: '{response.text}'")

        # Get response
        try:
            resp_json = response.json()
        except simplejson.JSONDecodeError as err:
            raise exceptions.APIError(f"Could not decode JSON response: '{err}'")

        # Check if project empty
        if "num_items" in resp_json and resp_json["num_items"] == 0:
            raise exceptions.NoDataError(f"Project '{self.project}' is empty.")

        # Get files
        files_folders = resp_json["files_folders"]

        # Sort the file/folders according to names
        sorted_files_folders = sorted(files_folders, key=lambda f: f["name"])

        # Create tree
        tree_title = escape(folder) or f"Files / directories in project: [green]{self.project}"
        tree = Tree(f"[bold magenta]{tree_title}")

        if not sorted_files_folders:
            raise exceptions.NoDataError(f"Could not find folder: '{escape(folder)}'")

        # Get max length of file name
        max_string = max([len(x["name"]) for x in sorted_files_folders])

        # Get max length of size string
        max_size = max(
            [
                len(
                    dds_cli.utils.format_api_response(
                        response=x["size"], key="Size", binary=self.binary
                    ).split(" ", maxsplit=1)[0]
                )
                for x in sorted_files_folders
                if show_size and "size" in x
            ],
            default=0,
        )

        # Visible folders
        visible_folders = []

        # Add items to tree
        for x in sorted_files_folders:
            # Check if string is folder
            is_folder = x.pop("folder")

            # Att 1 for folders due to trailing /
            tab = th.TextHandler.format_tabs(
                string_len=len(x["name"]) + (1 if is_folder else 0),
                max_string_len=max_string,
            )

            # Add formatting if folder and set string name
            line = ""
            if is_folder:
                line = "[bold deep_sky_blue3]"
                visible_folders.append(x["name"])
            line += escape(x["name"]) + ("/" if is_folder else "")

            # Add size to line if option specified
            if show_size and "size" in x:
                size = dds_cli.utils.format_api_response(
                    response=x["size"], key="Size", binary=self.binary
                )
                line += f"{tab}{size.split()[0]}"

                # Define space between number and size format
                tabs_bf_format = th.TextHandler.format_tabs(
                    string_len=len(size), max_string_len=max_size, tab_len=2
                )
                line += f"{tabs_bf_format}{size.split()[1]}"
            tree.add(line)

        # Print output to stdout
        if len(files_folders) + 5 > dds_cli.utils.console.height:
            with dds_cli.utils.console.pager():
                dds_cli.utils.console.print(Padding(tree, 1))
        else:
            dds_cli.utils.console.print(Padding(tree, 1))

        # Return variable
        return visible_folders
Example #6
0
    def get_status(self, show_history):
        """Get current status and status history of the project."""
        try:
            response = requests.get(
                DDSEndpoint.UPDATE_PROJ_STATUS,
                headers=self.token,
                params={"project": self.project},
                json={"history": show_history},
                timeout=DDSEndpoint.TIMEOUT,
            )
        except requests.exceptions.RequestException as err:
            raise exceptions.ApiRequestError(
                message=(
                    "Failed to get project status"
                    + (
                        ": The database seems to be down."
                        if isinstance(err, requests.exceptions.ConnectionError)
                        else "."
                    )
                )
            )

        # Check response
        if not response.ok:
            raise exceptions.APIError(f"Failed to get any projects: {response.text}")

        # Get result from API
        try:
            resp_json = response.json()
        except simplejson.JSONDecodeError as err:
            raise exceptions.APIError(f"Could not decode JSON response: {err}")
        else:
            current_status = resp_json.get("current_status")
            current_deadline = resp_json.get("current_deadline")
            status_out = f"Current status of {self.project}: {current_status}"
            deadline_out = ""
            if current_deadline:
                try:
                    date = pytz.timezone("UTC").localize(
                        datetime.datetime.strptime(current_deadline, "%a, %d %b %Y %H:%M:%S GMT")
                    )
                except ValueError as err:
                    raise exceptions.ApiResponseError(
                        f"Time zone mismatch: Incorrect zone '{current_deadline.split()[-1]}'"
                    )
                else:
                    current_deadline = date.astimezone(tzlocal.get_localzone()).strftime(
                        "%a, %d %b %Y %H:%M:%S %Z"
                    )
                deadline_out = f" with deadline {current_deadline}"
            dds_cli.utils.console.print(f"{status_out}{deadline_out}")
            if show_history:
                history = "Status history \n"
                for row in resp_json.get("history"):
                    try:
                        date = pytz.timezone("UTC").localize(
                            datetime.datetime.strptime(row[1], "%a, %d %b %Y %H:%M:%S GMT")
                        )
                    except ValueError as err:
                        raise exceptions.ApiResponseError(
                            f"Time zone mismatch: Incorrect zone '{row[1].split()[-1]}'"
                        )
                    else:
                        row[1] = date.astimezone(tzlocal.get_localzone()).strftime(
                            "%a, %d %b %Y %H:%M:%S %Z"
                        )
                    history += ", ".join(list(row)) + " \n"
                LOG.info(history)