# Path: mfr/core/provider.py
# class BaseProvider(metaclass=abc.ABCMeta):
# class ProviderMetadata:
#     def __init__(self, request, url, action=None):
#     def NAME(self):
#     def metadata(self):
#     def download(self):
#     def __init__(self, name, ext, content_type, unique_key, download_url, stable_id=None):
#     def serialize(self):
# 
# Path: mfr/core/exceptions.py
# class PluginError(waterbutler.core.exceptions.PluginError):
# class ExtensionError(PluginError):
# class RendererError(ExtensionError):
# class ExporterError(ExtensionError):
# class SubprocessError(ExporterError):
# class ProviderError(PluginError):
# class DownloadError(ProviderError):
# class MetadataError(ProviderError):
# class TooBigToRenderError(ProviderError):
# class DriverManagerError(PluginError):
# class MakeProviderError(DriverManagerError):
# class UnsupportedExtensionError(DriverManagerError):
# class MakeRendererError(UnsupportedExtensionError):
# class MakeExporterError(UnsupportedExtensionError):
#     __TYPE = 'plugin'
#     __TYPE = 'extension'
#     __TYPE = 'renderer'
#     __TYPE = 'exporter'
#     __TYPE = 'subprocess'
#     __TYPE = 'provider'
#     __TYPE = 'download'
#     __TYPE = 'metadata'
#     __TYPE = 'too_big_to_render'
#     __TYPE = 'drivermanager'
#     __TYPE = 'unsupported_extension'
#     def __init__(self, message, *args, code=500, **kwargs):
#     def as_html(self):
#     def _format_original_exception(self, exc):
#     def __init__(self, message, *args, extension: str='', **kwargs):
#     def __init__(self, message, *args, renderer_class: str='', **kwargs):
#     def __init__(self, message, *args, exporter_class: str='', **kwargs):
#     def __init__(self, message, *args, code: int=500, process: str='', cmd: str='',
#                  returncode: int=None, path: str='', **kwargs):
#     def __init__(self, message, *args, provider: str='', **kwargs):
#     def __init__(self, message, *args, download_url: str='', response: str='', **kwargs):
#     def __init__(self, message, *args, metadata_url: str='', response: str='', **kwargs):
#     def __init__(self, message, *args, requested_size: int=None, maximum_size: int=None,
#                  code: int=400, **kwargs):
#     def __init__(self, message, *args, namespace: str='', name: str='', invoke_on_load: bool=None,
#                  invoke_args: dict=None, **kwargs):
#     def __init__(self, message, *args, code: int=500, **kwargs):
#     def __init__(self, *args, code: int=400, handler_type: str='', **kwargs):
#     def __init__(self, *args, **kwargs):
#     def __init__(self, *args, **kwargs):


import os
import hashlib
import logging
import mimetypes
import aiohttp
from urllib.parse import urlparse
from waterbutler.core import streams
from mfr.core import provider
from mfr.core import exceptions




logger = logging.getLogger(__name__)


class HttpProvider(provider.BaseProvider):
    """Basic MFR provider.  Infers file metadata (extension, type) from the url. Downloads by
    issuing a GET to the url.
    """

    NAME = 'http'

    async def metadata(self):
        path = urlparse(self.url).path
        name, ext = os.path.splitext(os.path.split(path)[-1])
        content_type, _ = mimetypes.guess_type(self.url)
        unique_key = hashlib.sha256(self.url.encode('utf-8')).hexdigest()
        return provider.ProviderMetadata(name, ext, content_type, unique_key, self.url)

    async def download(self):
        response = await aiohttp.request('GET', self.url)
        if response.status >= 400:
            err_resp = await response.read()
            logger.error('Unable to download file: ({}) {}'.format(response.status, err_resp.decode('utf-8')))

# Path: mfr/core/provider.py
# class BaseProvider(metaclass=abc.ABCMeta):
# class ProviderMetadata:
#     def __init__(self, request, url, action=None):
#     def NAME(self):
#     def metadata(self):
#     def download(self):
#     def __init__(self, name, ext, content_type, unique_key, download_url, stable_id=None):
#     def serialize(self):
# 
# Path: mfr/core/exceptions.py
# class PluginError(waterbutler.core.exceptions.PluginError):
# class ExtensionError(PluginError):
# class RendererError(ExtensionError):
# class ExporterError(ExtensionError):
# class SubprocessError(ExporterError):
# class ProviderError(PluginError):
# class DownloadError(ProviderError):
# class MetadataError(ProviderError):
# class TooBigToRenderError(ProviderError):
# class DriverManagerError(PluginError):
# class MakeProviderError(DriverManagerError):
# class UnsupportedExtensionError(DriverManagerError):
# class MakeRendererError(UnsupportedExtensionError):
# class MakeExporterError(UnsupportedExtensionError):
#     __TYPE = 'plugin'
#     __TYPE = 'extension'
#     __TYPE = 'renderer'
#     __TYPE = 'exporter'
#     __TYPE = 'subprocess'
#     __TYPE = 'provider'
#     __TYPE = 'download'
#     __TYPE = 'metadata'
#     __TYPE = 'too_big_to_render'
#     __TYPE = 'drivermanager'
#     __TYPE = 'unsupported_extension'
#     def __init__(self, message, *args, code=500, **kwargs):
#     def as_html(self):
#     def _format_original_exception(self, exc):
#     def __init__(self, message, *args, extension: str='', **kwargs):
#     def __init__(self, message, *args, renderer_class: str='', **kwargs):
#     def __init__(self, message, *args, exporter_class: str='', **kwargs):
#     def __init__(self, message, *args, code: int=500, process: str='', cmd: str='',
#                  returncode: int=None, path: str='', **kwargs):
#     def __init__(self, message, *args, provider: str='', **kwargs):
#     def __init__(self, message, *args, download_url: str='', response: str='', **kwargs):
#     def __init__(self, message, *args, metadata_url: str='', response: str='', **kwargs):
#     def __init__(self, message, *args, requested_size: int=None, maximum_size: int=None,
#                  code: int=400, **kwargs):
#     def __init__(self, message, *args, namespace: str='', name: str='', invoke_on_load: bool=None,
#                  invoke_args: dict=None, **kwargs):
#     def __init__(self, message, *args, code: int=500, **kwargs):
#     def __init__(self, *args, code: int=400, handler_type: str='', **kwargs):
#     def __init__(self, *args, **kwargs):
#     def __init__(self, *args, **kwargs):


# Path: mfr/providers/http/provider.py
import os
import hashlib
import logging
import mimetypes
import aiohttp
from urllib.parse import urlparse
from waterbutler.core import streams
from mfr.core import provider
from mfr.core import exceptions





logger = logging.getLogger(__name__)


class HttpProvider(provider.BaseProvider):
    """Basic MFR provider.  Infers file metadata (extension, type) from the url. Downloads by
    issuing a GET to the url.
    """

    NAME = 'http'

    async def metadata(self):
        path = urlparse(self.url).path
        name, ext = os.path.splitext(os.path.split(path)[-1])
        content_type, _ = mimetypes.guess_type(self.url)
        unique_key = hashlib.sha256(self.url.encode('utf-8')).hexdigest()
        return provider.ProviderMetadata(name, ext, content_type, unique_key, self.url)

    async def download(self):
        response = await aiohttp.request('GET', self.url)
        if response.status >= 400:
            err_resp = await response.read()
            logger.error('Unable to download file: ({}) {}'.format(response.status, err_resp.decode('utf-8')))

            raise exceptions.DownloadError(