# Path: statik/errors.py
# class ProjectConfigurationError(StatikError):
#     """For generic project configuration-related errors."""
#     error_kind = "Project configuration error"
#     exit_code = 2
# 
# class DeploymentError(StatikError):
#     """For errors relating to deployment of built projects."""
#     error_kind = "Deployment-related error"
#     exit_code = 9
# 
# Path: statik/deploy/base.py
# class DeploymentMethod(object):
#     """An abstract method for handling deployment."""
# 
#     def __init__(self, config, error_context=None):
#         """Must validate the given configuration for this deployment method and raise an exception
#         if it's invalid."""
#         raise NotImplementedError
# 
#     def execute(self, source_path):
#         """Must actually execute the implemented deployment method."""
#         raise NotImplementedError


import os
import os.path
import requests
import hashlib
import time
import json
import logging
from collections import OrderedDict, namedtuple
from datetime import datetime
from dateutil.parser import parse as dateutil_parse
from urllib.parse import quote as urllib_quote
from ..errors import ProjectConfigurationError, DeploymentError
from .base import DeploymentMethod
        for filename, df in hashes_by_filename.items():
            payload['files'][filename] = df.sha1sum
        logger.debug("Attempting to send deployment data:\n%s" % json.dumps(payload, indent=2))
        resp = self.netlify_post(
            '/sites/%s/deploys' % self.site_id,
            payload,
        )
        if resp.status_code >= 400:
            raise DeploymentError("Failed to create Netlify deployment: %s" % resp.text)
        deployment = resp.json()
        logger.debug("Got response:\n%s" % json.dumps(deployment, indent=2))
        if deployment.get('state') == 'preparing':
            deployment = self.netlify_wait_for_deployment(deployment['id'])
        return deployment

    def netlify_wait_for_deployment(self, deploy_id, max_wait=60*5):
        start_time = datetime.now().timestamp()
        while True:
            resp = self.netlify_get('/sites/%s/deploys/%s' % (self.site_id, deploy_id))
            if resp.status_code >= 400:
                raise DeploymentError(
                    "Got error from Netlify API while waiting for deployment: %s" % resp.text,
                )
            deployment = resp.json()
            if deployment.get('state') in ['prepared', 'uploading', 'uploaded', 'ready']:
                logger.debug("Netlify is ready for deployment:\n%s" % json.dumps(deployment,
                    indent=2))
                return deployment

            if datetime.now().timestamp() - start_time > max_wait:

# Path: statik/errors.py
# class ProjectConfigurationError(StatikError):
#     """For generic project configuration-related errors."""
#     error_kind = "Project configuration error"
#     exit_code = 2
# 
# class DeploymentError(StatikError):
#     """For errors relating to deployment of built projects."""
#     error_kind = "Deployment-related error"
#     exit_code = 9
# 
# Path: statik/deploy/base.py
# class DeploymentMethod(object):
#     """An abstract method for handling deployment."""
# 
#     def __init__(self, config, error_context=None):
#         """Must validate the given configuration for this deployment method and raise an exception
#         if it's invalid."""
#         raise NotImplementedError
# 
#     def execute(self, source_path):
#         """Must actually execute the implemented deployment method."""
#         raise NotImplementedError


# Path: statik/deploy/netlify.py
import os
import os.path
import requests
import hashlib
import time
import json
import logging
from collections import OrderedDict, namedtuple
from datetime import datetime
from dateutil.parser import parse as dateutil_parse
from urllib.parse import quote as urllib_quote
from ..errors import ProjectConfigurationError, DeploymentError
from .base import DeploymentMethod

        for filename, df in hashes_by_filename.items():
            payload['files'][filename] = df.sha1sum
        logger.debug("Attempting to send deployment data:\n%s" % json.dumps(payload, indent=2))
        resp = self.netlify_post(
            '/sites/%s/deploys' % self.site_id,
            payload,
        )
        if resp.status_code >= 400:
            raise DeploymentError("Failed to create Netlify deployment: %s" % resp.text)
        deployment = resp.json()
        logger.debug("Got response:\n%s" % json.dumps(deployment, indent=2))
        if deployment.get('state') == 'preparing':
            deployment = self.netlify_wait_for_deployment(deployment['id'])
        return deployment

    def netlify_wait_for_deployment(self, deploy_id, max_wait=60*5):
        start_time = datetime.now().timestamp()
        while True:
            resp = self.netlify_get('/sites/%s/deploys/%s' % (self.site_id, deploy_id))
            if resp.status_code >= 400:
                raise DeploymentError(
                    "Got error from Netlify API while waiting for deployment: %s" % resp.text,
                )
            deployment = resp.json()
            if deployment.get('state') in ['prepared', 'uploading', 'uploaded', 'ready']:
                logger.debug("Netlify is ready for deployment:\n%s" % json.dumps(deployment,
                    indent=2))
                return deployment

            if datetime.now().timestamp() - start_time > max_wait:

                raise DeploymentError("Timed out while waiting for Netlify to become ready for deployment")