summaryrefslogtreecommitdiff
path: root/src/wii/filesystem.py
blob: b6b81030687f6c59d54fc17a47a873fce3e73a2d (plain)
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
114
115
116
117
118
119
120
121
122
123
124
import weakref

class WiiFSObject(object):
	def __init__(self):
		self._parent_ref = None
		self._name = ''
		self._low_name = ''
	
	@property
	def parent(self):
		ref = self._parent_ref
		return (ref() if ref else None)

	@parent.setter
	def parent(self, value):
		self._parent_ref = weakref.ref(value)
	
	@parent.deleter
	def parent(self):
		self._parent_ref = None
	

	@property
	def name(self):
		return self._name

	@name.setter
	def name(self, value):
		self._name = value
		self._low_name = value.lower()

	
	def unlinkFromParent(self):
		if self.parent == None:
			return

		if self.parent.isDirectory():
			self.parent.children.remove(self)

		del self.parent

	def isFile(self): return False
	def isDirectory(self): return False


class WiiFile(WiiFSObject):
	def __init__(self):
		WiiFSObject.__init__(self)
		self.data = None
	
	def isFile(self): return True


class WiiDirectory(WiiFSObject):
	def __init__(self):
		WiiFSObject.__init__(self)
		self.children = []
	
	def isDirectory(self): return True

	def findByName(self, name, recursive):
		return self._findByName(name.lower(), recursive)

	def _findByName(self, lowercase_name, recursive):
		for obj in self.children:
			if obj._low_name == lowercase_name:
				return obj

			if recursive and obj.isDirectory():
				tryThis = obj._findByName(lowercase_name, recursive)
				if tryThis:
					return tryThis

		return None

	def resolvePath(self, path):
		components = path.split('/')
		currentDir = self

		# special case: handle absolute paths
		if components[0] == '':
			while currentDir.parent:
				currentDir = currentDir.parent

			del components[0]

		while len(components) > 0:
			bit = components.pop(0)
			nextObj = None

			if bit == '.':
				nextObj = currentDir
			elif bit == '..':
				nextObj = currentDir.parent
			else:
				nextObj = currentDir.findByName(bit, False)

			if nextObj is None:
				print("failed to resolve path %s: missing component %s" % (path, bit))
				return None

			if len(components) == 0:
				return nextObj

			if not nextObj.isDirectory():
				print("failed to resolve path %s: component %s is not a directory" % (path, bit))
				return None

			# has to be a directory so just continue
			currentDir = nextObj

		print("wtf? %s" % path)
		return None

	def addChild(self, obj):
		if self.findByName(obj.name, False):
			return False

		obj.unlinkFromParent()
		self.children.append(obj)
		obj.parent = self

		return True