# Path: ddsc/core/ddsapi.py
# class DSResourceNotConsistentError(DataServiceError):
#     """
#     Exception thrown when a DukeDS resource is not in a consistent state.
#     The resource may become consistent at some future point in time so users can retry.
#     """
#     def __init__(self, response, url_suffix, request_data):
#         super(self.__class__, self).__init__(response, url_suffix, request_data)
# 
# class DSHashMismatchError(DataServiceError):
#     """
#     Exception thrown when a DukeDS resource has an incorrect hash.
#     """
#     pass
# 
# class DataServiceError(Exception):
#     """
#     Error that wraps up info about it and creates an informative string.
#     """
#     def __init__(self, response, url_suffix, request_data):
#         """
#         Create exception for failed response.
#         :param response: requests.Response response that was in error
#         :param url_suffix: str url we were trying to connect to
#         :param request_data: object data we were sending to url
#         """
#         resp_json = None
#         try:
#             resp_json = response.json()
#         except:
#             resp_json = {}
#         if response.status_code == 500:
#             if resp_json and not resp_json.get('reason'):
#                 resp_json = {'reason': 'Internal Server Error', 'suggestion': 'Contact DDS support.'}
#         Exception.__init__(self, 'Error {} on {}\nReason:{}\nSuggestion:{}'.format(
#             response.status_code, url_suffix, resp_json.get('reason', resp_json.get('error', '')),
#             resp_json.get('suggestion', '')
#         ))
#         self.response = resp_json
#         self.url_suffix = url_suffix
#         self.request_data = request_data
#         self.status_code = response.status_code


import time
from ddsc.core.ddsapi import DSResourceNotConsistentError, DSHashMismatchError, DataServiceError
from tabulate import tabulate
                upload_details.message(),
                upload_details.file_id(),
                upload_details.remote_path
            ])
        return headers, data

    def delete_bad_uploads(self):
        for bad_upload in self.get_bad_uploads():
            bad_upload.dds_file.delete()

    def print_bad_uploads_table(self):
        print("ERROR: Project {} is not in a consistent state.\n".format(self.project.name))
        print("Please wait while file uploads are checked.\nThis process can take quite a while.")
        headers, data = self.get_bad_uploads_table_data()
        print(tabulate(data, headers=headers))
        print("\nNOTE: Inconsistent files should resolve in a few minutes after starting.")
        print("\nAn inconsistent file can be deleted by running:\n ddsclient delete -p <ProjectName> --path <RemotePath>")
        print()

    def wait_for_consistency(self, wait_sec=5):
        while True:
            try:
                print("Checking files for project {}.".format(self.project.name))
                self._try_fetch_project_files()
                # if we are able to fetch all files project is in a consistent state
                print("Project {} is consistent.".format(self.project.name))
                return True
            except DSResourceNotConsistentError:
                print("Project not consistent yet. Waiting.")
                time.sleep(wait_sec)

# Path: ddsc/core/ddsapi.py
# class DSResourceNotConsistentError(DataServiceError):
#     """
#     Exception thrown when a DukeDS resource is not in a consistent state.
#     The resource may become consistent at some future point in time so users can retry.
#     """
#     def __init__(self, response, url_suffix, request_data):
#         super(self.__class__, self).__init__(response, url_suffix, request_data)
# 
# class DSHashMismatchError(DataServiceError):
#     """
#     Exception thrown when a DukeDS resource has an incorrect hash.
#     """
#     pass
# 
# class DataServiceError(Exception):
#     """
#     Error that wraps up info about it and creates an informative string.
#     """
#     def __init__(self, response, url_suffix, request_data):
#         """
#         Create exception for failed response.
#         :param response: requests.Response response that was in error
#         :param url_suffix: str url we were trying to connect to
#         :param request_data: object data we were sending to url
#         """
#         resp_json = None
#         try:
#             resp_json = response.json()
#         except:
#             resp_json = {}
#         if response.status_code == 500:
#             if resp_json and not resp_json.get('reason'):
#                 resp_json = {'reason': 'Internal Server Error', 'suggestion': 'Contact DDS support.'}
#         Exception.__init__(self, 'Error {} on {}\nReason:{}\nSuggestion:{}'.format(
#             response.status_code, url_suffix, resp_json.get('reason', resp_json.get('error', '')),
#             resp_json.get('suggestion', '')
#         ))
#         self.response = resp_json
#         self.url_suffix = url_suffix
#         self.request_data = request_data
#         self.status_code = response.status_code


# Path: ddsc/core/consistency.py
import time
from ddsc.core.ddsapi import DSResourceNotConsistentError, DSHashMismatchError, DataServiceError
from tabulate import tabulate

                upload_details.message(),
                upload_details.file_id(),
                upload_details.remote_path
            ])
        return headers, data

    def delete_bad_uploads(self):
        for bad_upload in self.get_bad_uploads():
            bad_upload.dds_file.delete()

    def print_bad_uploads_table(self):
        print("ERROR: Project {} is not in a consistent state.\n".format(self.project.name))
        print("Please wait while file uploads are checked.\nThis process can take quite a while.")
        headers, data = self.get_bad_uploads_table_data()
        print(tabulate(data, headers=headers))
        print("\nNOTE: Inconsistent files should resolve in a few minutes after starting.")
        print("\nAn inconsistent file can be deleted by running:\n ddsclient delete -p <ProjectName> --path <RemotePath>")
        print()

    def wait_for_consistency(self, wait_sec=5):
        while True:
            try:
                print("Checking files for project {}.".format(self.project.name))
                self._try_fetch_project_files()
                # if we are able to fetch all files project is in a consistent state
                print("Project {} is consistent.".format(self.project.name))
                return True
            except DSResourceNotConsistentError:
                print("Project not consistent yet. Waiting.")
                time.sleep(wait_sec)

            except DSHashMismatchError: