csvpath.managers.files.file_cacher

 1import os
 2from typing import Dict, List, Tuple
 3from csvpath.util.line_counter import LineCounter
 4from csvpath.util.line_monitor import LineMonitor
 5from csvpath.util.cache import Cache
 6from csvpath.util.exceptions import InputException, FileException
 7
 8
 9class FileCacher:
10    """@private"""
11    def __init__(self, csvpaths=None):
12        self.csvpaths = csvpaths
13        self.cache = Cache(self.csvpaths)
14        self.pathed_lines_and_headers = {}
15
16    def get_new_line_monitor(self, filename: str) -> LineMonitor:
17        if filename is None:
18            raise ValueError("Filename cannot be None")
19        if filename not in self.pathed_lines_and_headers:
20            self._find_lines_and_headers(filename)
21        lm = self.pathed_lines_and_headers[filename][0]
22        lm = lm.copy()
23        return lm
24
25    def get_original_headers(self, filename: str) -> List[str]:
26        if filename not in self.pathed_lines_and_headers:
27            self._find_lines_and_headers(filename)
28        return self.pathed_lines_and_headers[filename][1][:]
29
30    def _find_lines_and_headers(self, filename: str) -> None:
31        if filename is None:
32            raise ValueError("Filename cannot be None")
33        lm, headers = self._cached_lines_and_headers(filename)
34        if lm is None or headers is None:
35            lc = LineCounter(self.csvpaths)
36            lm, headers = lc.get_lines_and_headers(filename)
37            self._cache_lines_and_headers(filename, lm, headers)
38        self.pathed_lines_and_headers[filename] = (lm, headers)
39
40    def _cached_lines_and_headers(self, filename: str) -> Tuple[LineMonitor, List[str]]:
41        if filename is None:
42            raise ValueError("Filename cannot be None")
43        lm = LineMonitor()
44        json = self.cache.cached_text(filename, "json")
45        if json is not None and not json.strip() == "":
46            lm.load(json)
47        else:
48            return (None, None)
49        headers = self.cache.cached_text(filename, "csv")
50        return (lm, headers)
51
52    def _cache_lines_and_headers(
53        self, filename, lm: LineMonitor, headers: List[str]
54    ) -> None:
55        jstr = lm.dump()
56        self.cache.cache_text(filename, "json", jstr)
57        self.cache.cache_text(filename, "csv", ",".join(headers))