summary refs log tree commit diff stats
path: root/ranger/fsobject.py
blob: 35d0d5b39790d6af39c203ca5fc0f5ddace51c4e (plain) (blame)
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
class NotLoadedYet(Exception):
	pass

T_FILE = 'file'
T_DIRECTORY = 'directory'
T_UNKNOWN = 'unknown'
T_NONEXISTANT = 'nonexistant'

BAD_INFO = None

CONTAINER_EXTENSIONS = 'rar zip tar gz bz bz2 tgz 7z iso cab'.split()
DOCUMENT_EXTENSIONS = 'pdf doc ppt odt'.split()
DOCUMENT_BASENAMES = 'README TODO LICENSE'.split()

from ranger.shared import MimeTypeAware, FileManagerAware
class FileSystemObject(MimeTypeAware, FileManagerAware):

	def __init__(self, path):
		MimeTypeAware.__init__(self)
		if type(self) == FileSystemObject:
			raise TypeError("FileSystemObject is an abstract class and cannot be initialized.")

		from os.path import basename, dirname

		self.path = path
		self.basename = basename(path)
		self.dirname = dirname(path)
		try:
			self.extension = self.basename[self.basename.rindex('.') + 1:]
		except ValueError:
			self.extension = None
		self.exists = False
		self.accessible = False
		self.marked = False
		self.tagged = False
		self.frozen = False
		self.loaded = False
		self.runnable = False
		self.islink = False
		self.brokenlink = False
		self.stat = None
		self.infostring = None
		self.permissions = None
		self.type = T_UNKNOWN

		self.set_mimetype()
		self.use()
	
	def __str__(self):
		return str(self.path)

	def use(self):
		import time
		self.last_used = time.time()
	
	def is_older_than(self, seconds):
		import time
		return self.last_used + seconds < time.time()
	
	def set_mimetype(self):
		try:
			self.mimetype = self.mimetypes[self.extension]
		except KeyError:
			self.mimetype = ''

		self.video = self.mimetype.startswith('video')
		self.image = self.mimetype.startswith('image')
		self.audio = self.mimetype.startswith('audio')
		self.media = self.video or self.image or self.audio
		self.document = self.mimetype.startswith('text') or (self.extension in DOCUMENT_EXTENSIONS) or (self.basename in DOCUMENT_BASENAMES)
		self.container = self.extension in CONTAINER_EXTENSIONS

		keys = ('video', 'audio', 'image', 'media', 'document', 'container')
		self.mimetype_tuple = tuple(key for key in keys if getattr(self, key))

		if self.mimetype == '':
			self.mimetype = None

	# load() reads useful information about the file from the file system
	# and caches it in instance attributes.
	def load(self):
		import os
		from ranger.ext import human_readable

		self.loaded = True

		if os.access(self.path, os.F_OK):
			self.stat = os.stat(self.path)
			self.islink = os.path.islink(self.path)
			self.exists = True
			self.accessible = True

			if os.path.isdir(self.path):
				self.type = T_DIRECTORY
				try:
					self.size = len(os.listdir(self.path))
					self.infostring = ' %d' % self.size
					self.runnable = True
				except OSError:
					self.infostring = BAD_INFO
					self.runnable = False
					self.accessible = False
			elif os.path.isfile(self.path):
				self.type = T_FILE
				self.size = self.stat.st_size
				self.infostring = ' ' + human_readable(self.stat.st_size)
			else:
				self.type = T_UNKNOWN
				self.infostring = None

		else:
			self.stat = None
			self.islink = False
			self.infostring = None
			self.type = T_NONEXISTANT
			self.exists = False
			self.runnable = False
			self.accessible = False

	def load_once(self):
		if not self.loaded:
			self.load()
			return True
		return False

	def go(self):
		self.fm.enter_dir(self.path)

	def load_if_outdated(self):
		if self.load_once(): return True

		import os
		real_mtime = os.stat(self.path).st_mtime
		cached_mtime = self.stat.st_mtime

		if real_mtime != cached_mtime:
			self.load()
			return True
		return False