"""
The statusbar displays information about the current file and directory.
On the left side, there is a display similar to what "ls -l" would
print for the current file. The right side shows directory information
such as the space used by all the files in this directory.
"""
from . import Widget
from pwd import getpwuid
from grp import getgrgid
from os import getuid
from time import strftime, localtime
from ranger.gui.bar import Bar
class StatusBar(Widget):
__doc__ = __doc__
owners = {}
groups = {}
timeformat = '%Y-%m-%d %H:%M'
override = None
old_cf = None
old_mtime = None
old_wid = None
result = None
def __init__(self, win, column=None):
Widget.__init__(self, win)
self.column = column
def draw(self):
"""Draw the statusbar"""
# each item in the returned array looks like:
# [ list_with_color_tags, string ]
# [ ['permissions', 'allowed'], '-rwxr-xr-x' ]
if self.override and isinstance(self.override, str):
self._draw_message()
else:
try:
mtime = self.env.cf.stat.st_mtime
except:
mtime = -1
if not self.result or self.old_cf != self.env.cf or \
mtime != self.old_mtime or self.old_wid != self.wid:
self.old_mtime = mtime
self.old_cf = self.env.cf
self.old_wid = self.wid
self._calc_bar()
self._print_result(self.result)
def _calc_bar(self):
bar = Bar('in_statusbar')
self._get_left_part(bar)
self._get_right_part(bar)
bar.shrink_by_removing(self.wid)
self.result = bar.combine()
def _draw_message(self):
highlight = True
space_left = self.wid
starting_point = self.x
for string in self.override.split('//'):
highlight = not highlight
if highlight:
self.color('in_statusbar', 'text', 'highlight')
else:
self.color('in_statusbar', 'text')
try:
self.win.addnstr(self.y, starting_point, string, space_left)
except:
break
space_left -= len(string)
starting_point += len(string)
# if starting_point >= self.wid:
# break
def _get_left_part(self, bar):
left = bar.left
if self.column is not None:
target = self.column.target.pointed_obj
else:
target = self.env.at_level(0).pointed_obj
if target is None:
return
if target.accessible is False:
return
perms = target.get_permission_string()
how = getuid() == target.stat.st_uid and 'good' or 'bad'
left.add(perms, 'permissions', how)
left.add_space()
left.add(str(target.stat.st_nlink), 'nlink')
left.add_space()
left.add(self._get_owner(target), 'owner')
left.add_space()
left.add(self._get_group(target), 'group')
left.add_space()
if target.islink:
how = target.exists and 'good' or 'bad'
left.add('-> ' + target.readlink, 'link', how)
else:
left.add(strftime(self.timeformat,
localtime(target.stat.st_mtime)), 'mtime')
def _get_owner(self, target):
uid = target.stat.st_uid
try:
return self.owners[uid]
except KeyError:
try:
self.owners[uid] = getpwuid(uid)[0]
return self.owners[uid]
except KeyError:
return str(uid)
def _get_group(self, target):
gid = target.stat.st_gid
try:
return self.groups[gid]
except KeyError:
try:
self.groups[gid] = getgrgid(gid)[0]
return self.groups[gid]
except KeyError:
return str(gid)
def _get_right_part(self, bar):
right = bar.right
if self.column is None:
return
target = self.column.target
if not target.content_loaded or not target.accessible:
return
pos = target.scroll_begin
max_pos = len(target) - self.column.hei
base = 'scroll'
if target.marked_items:
# Indicate that there are marked files. Useful if you scroll
# away and don't see them anymore.
right.add('Mrk', base, 'marked')
elif max_pos > 0:
if pos == 0:
right.add('Top', base, 'top')
elif pos >= max_pos:
right.add('Bot', base, 'bot')
else:
right.add('{0:0>.0f}%'.format(100.0 * pos / max_pos),
base, 'percentage')
else:
right.add('All', base, 'all')
def _print_result(self, result):
import _curses
self.win.move(0, 0)
for part in result:
self.color(*part.lst)
self.addstr(part.string)
self.color_reset()