-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimple_files.py
113 lines (89 loc) · 3.52 KB
/
simple_files.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
from collections import MutableMapping
import os
import pandas
import yaml
__author__ = 'andriod'
class FileHolder(MutableMapping, object):
next_type = None
def __init__(self, name, *prev_path):
"""FileHolders hold a section of the data and are matched in the file system with a matching directory or file
:type name: str - name of the file or directory corresponding to this instance
:param prev_path: - tuple of the FileHolders in the to this point
"""
self.name = name
self.path = prev_path + (self,)
self.is_dir = os.path.isdir(self.file_path)
self._yaml_obj = None
self._cache = {}
if self.next_type is None:
self.next_type = type(self)
def __getitem__(self, item):
"""Overriding the [indexing] operation
:type item: str - the key being accessed by [indexing]
:return:
"""
if item not in self._cache:
ret = self.create_sub_obj(item)
self._cache[item] = ret
return self._cache[item]
def __getattr__(self, item):
"""Overriding attribute access
:type item: str - attribute requested
:return: :raise AttributeError:
"""
if item not in ['yaml_dict', 'file_path'] and not item[0] == "_":
return self[item]
else:
raise AttributeError
def create_sub_obj(self, item):
"""In both cases of .attribute and [indexing] we actually just continue to walk the tree
:type item: str - the name of the next object
:return: a newly created object, caller is responsible for caching
"""
if self.yaml_obj:
return self.yaml_obj[item]
elif os.path.isfile(os.path.join(self.file_path, item) + ".csv"):
return pandas.DataFrame.from_csv(os.path.join(self.file_path, item) + ".csv")
return self.next_type(item, *self.path)
@property
def yaml_obj(self):
if self._yaml_obj is not None:
return self._yaml_obj
elif os.path.isfile(self.file_path + ".yaml"):
self._yaml_obj = yaml.load(open(self.file_path + ".yaml"))
return self._yaml_obj
else:
return None
@property
def file_path(self):
return str(os.path.join(*[x.name for x in self.path]))
@property
def value(self):
if self.is_dir:
return "Directory, no value"
elif os.path.isfile(self.file_path):
return open(self.file_path).read()
elif os.path.isfile(self.file_path + ".yaml"):
return yaml.load(open(self.file_path + ".yaml"))
def __repr__(self, *args, **kwargs):
return "< {path} - {value} ".format(path=",".join(x.name for x in self.path), value=self.value)
def __str__(self, *args, **kwargs):
return str(self.value)
def __iter__(self):
if self.is_dir:
return (self[os.path.splitext(os.path.basename(path))[0]] for path in os.listdir(self.file_path))
elif self.yaml_obj is not None:
return iter(self.yaml_obj)
else:
return iter([]) #empty iter, we have no case for this now
def __len__(self):
if self.is_dir:
return len(os.listdir(self.file_path))
elif self.yaml_obj is not None:
return len(self.yaml_obj)
else:
return 0 #empty iter, we have no case for this now
def __delitem__(self, key):
del self._cache[key]
def __setitem__(self, key, value):
self._cache[key] = value