validata_util.py 1.58 KB
Newer Older
1 2 3
""" Call validation code """

import logging
Christophe Benz's avatar
Christophe Benz committed
4
from abc import ABC, abstractmethod
5
from io import BytesIO
6
from pathlib import Path
Christophe Benz's avatar
Christophe Benz committed
7
from urllib.parse import urlparse
8

9 10 11
log = logging.getLogger(__name__)


12 13
class ValidataResource(ABC):
    """A resource to validate: url or uploaded file"""
14

15
    def __init__(self, type_):
Pierre Dittgen's avatar
wip  
Pierre Dittgen committed
16
        self.type = type_
17

18 19 20 21 22 23 24 25 26 27 28 29 30
    @abstractmethod
    def build_tabulator_stream_args(self):
        """return (source, option_dict)"""
        pass


class URLValidataResource(ValidataResource):
    """URL resource"""

    def __init__(self, url):
        """Built from URL"""
        super().__init__('url')
        self.url = url
Christophe Benz's avatar
Christophe Benz committed
31
        self.filename = Path(urlparse(url).path).name
32 33 34 35

    def build_tabulator_stream_args(self):
        """URL implementation"""
        return (self.url, {})
36 37


38 39
class UploadedFileValidataResource(ValidataResource):
    """Uploaded file resource"""
Pierre Dittgen's avatar
wip  
Pierre Dittgen committed
40

41 42 43 44 45
    def __init__(self, filename, bytes_content):
        """Built from file name and content"""
        super().__init__('file')
        self.filename = filename
        self.content = bytes_content
Pierre Dittgen's avatar
wip  
Pierre Dittgen committed
46

47 48
    def build_reader(self):
        return BytesIO(self.content)
49

Pierre Dittgen's avatar
Pierre Dittgen committed
50
    def __detect_format_from_file_extension(self):
51 52 53 54
        ext = Path(self.filename).suffix
        if ext in ('.csv', '.tsv', '.ods', '.xls', '.xlsx'):
            return ext[1:]
        return None
55

56 57
    def build_tabulator_stream_args(self):
        """Uploaded file implementation"""
58 59
        options = {
            'scheme': 'stream',
Pierre Dittgen's avatar
Pierre Dittgen committed
60
            'format': self.__detect_format_from_file_extension()
61 62
        }
        return (self.build_reader(), options)