Share Pastebin
Guest
Public paste!

Untitled

By: a guest | Feb 9th, 2010 | Syntax: None | Size: 7.69 KB | Hits: 11 | Expires: Never
Copy text to clipboard
  1. import curses
  2. import sys
  3. import os
  4. import time
  5. from curses import panel
  6. from curses.wrapper import wrapper
  7. from subprocess import Popen, PIPE
  8.  
  9. #shamelessly ripped from http://stackoverflow.com/questions/123958/how-to-get-set-logical-directory-path-in-python
  10. class CwdKeeper(object):
  11.     def __init__(self):
  12.         self._cwd = os.environ.get("PWD")
  13.         if self._cwd is None: # no environment. fall back to calling pwd on shell
  14.            self._cwd = Popen('pwd', stdout=PIPE).communicate()[0].strip()
  15.         self._os_getcwd = os.getcwd
  16.         self._os_chdir = os.chdir
  17.  
  18.     def chdir(self, path):
  19.         if not self._cwd:
  20.             return self._os_chdir(path)
  21.         p = os.path.normpath(os.path.join(self._cwd, path))
  22.         result = self._os_chdir(p)
  23.         self._cwd = p
  24.         os.environ["PWD"] = p
  25.         return result
  26.  
  27.     def getcwd(self):
  28.         if not self._cwd:
  29.             return self._os_getcwd()
  30.         return self._cwd
  31.  
  32.  
  33. class Container:
  34.         pass
  35.        
  36. def drawbottom(mainwind, width, height, status):
  37.         mainwind.move(height-2, 1)
  38.         mainwind.clrtoeol()
  39.         mainwind.addch(height-2, width-1, curses.ACS_VLINE)
  40.         mainwind.move(height-2, 1)
  41.         mainwind.addstr(status)
  42.         mainwind.refresh()
  43.  
  44. def setupdir(mainwind, infowind, width, height, currdir):
  45.         global d
  46.         mainwind.move(1, 1)
  47.         mainwind.clrtoeol()
  48.         mainwind.addch(1, width-1, curses.ACS_VLINE)
  49.         mainwind.move(1, 1)
  50.         mainwind.addstr("Path: " + currdir)
  51.         mainwind.touchwin()
  52.         mainwind.noutrefresh()
  53.         d.l = os.listdir(currdir) #list of the current dir
  54.         if len(d.l) == 0:
  55.                 d.l.append("<EMPTY>")
  56.         d.i = {} #file info
  57.         d.p = curses.newpad(len(d.l), width-3)
  58.         d.selected = 0
  59.         d.oldselected = 0
  60.         d.scroll = 0
  61.         d.bar = 0
  62.         #d.oldbar = 0
  63.         idx = 0
  64.         for x in d.l[:]:
  65.                 if x[0] == "." and d.invisible:
  66.                         d.l.remove(x)
  67.                         continue
  68.                 d.p.move(idx, 0)
  69.                 if os.path.isdir(x):
  70.                         d.i[x] = 1
  71.                         d.p.addstr(x, curses.color_pair(1))
  72.                 else:
  73.                         d.i[x] = 0
  74.                         d.p.addstr(x)
  75.                 idx = idx + 1
  76.         length = len(d.l)
  77.         if length == 0:
  78.                 d.l.append("<EMPTY>")
  79.                 d.i["<EMPTY>"] = 0
  80.         if d.l[0] == "<EMPTY>" and len(d.l) == 1:
  81.                 length = 0
  82.         s = str(length) + " file"
  83.         if length != 1:
  84.                 s = s + "s"
  85.         mainwind.addstr(1, width-2-len(s), s)
  86.         mainwind.addch(3, width-2, curses.ACS_UARROW)
  87.         mainwind.addch(height-4, width-2, curses.ACS_DARROW)
  88.         for x in range(4, height-4):
  89.                 mainwind.addch(x, width-2, curses.ACS_VLINE)
  90.         drawdir(mainwind, infowind, width, height)
  91.  
  92. def drawdir(mainwind, infowind, width, height):
  93.         global d
  94.         d.p.move(d.oldselected, 0)
  95.         if d.i[d.l[d.oldselected]] == 1:
  96.                 d.p.addstr(d.l[d.oldselected], curses.color_pair(1))
  97.         else:
  98.                 d.p.addstr(d.l[d.oldselected])
  99.         d.p.move(d.selected, 0)
  100.         d.p.addstr(d.l[d.selected], curses.A_REVERSE)
  101.         d.p.noutrefresh(d.scroll, 0, 3, 1, height-4, width-2)
  102.         mainwind.addch(d.bar+4, width-2, curses.ACS_VLINE)
  103.         try:
  104.                 d.bar = int((d.selected*1.0/(len(d.l)-1))*(height-9))
  105.         except:
  106.                 d.bar = 0
  107.         #raise Exception(d.bar, d.selected, height-8, len(d.l)-1, (d.selected*1.0/(len(d.l)-1)))
  108.         mainwind.addch(d.bar+4, width-2, " ", curses.A_REVERSE)
  109.         mainwind.noutrefresh()
  110.         if d.info:
  111.                 infowind.erase()
  112.                 infowind.box()
  113.                 infowind.hline(2, 0, curses.ACS_HLINE, 50)
  114.                 infowind.addch(2, 0, curses.ACS_LTEE)
  115.                 infowind.addch(2, 49, curses.ACS_RTEE)
  116.                 fname = d.l[d.selected]
  117.                 if len(fname) > 42:
  118.                         fname = fname[:-(len(fname)-42+3)] + "..."
  119.                 infowind.addstr(1, 1, "File: " + fname)
  120.                 statcall = os.stat(d.l[d.selected])
  121.                 size = statcall.st_size
  122.                 suffixes = ["B", "KB", "MB", "GB", "TB"]
  123.                 for suffix in suffixes:
  124.                         if size > 1024:
  125.                                 size /= 1024
  126.                         else:
  127.                                 break
  128.                 infowind.addstr(3, 1, "File size: " + str(size) + suffix + " (" + str(statcall.st_size) + " bytes)")
  129.                 permslist = ["x", "w", "r"]
  130.                 tlist = range(9)
  131.                 tlist.reverse()
  132.                 if os.path.isdir(d.l[d.selected]):
  133.                         permstr = "d"
  134.                 else:
  135.                         permstr = "-"
  136.                 for num in tlist:
  137.                         if statcall.st_mode & (1 << num) > 0:
  138.                                 permstr = permstr + permslist[num%3]
  139.                         else:
  140.                                 permstr = permstr + "-"
  141.                 infowind.addstr(4, 1, "Permissions: " + permstr)
  142.                 infowind.addstr(5, 1, time.strftime("Last modification: %c", time.localtime(statcall.st_mtime)))
  143.                 infowind.noutrefresh()
  144.         curses.doupdate()
  145.  
  146. def main(mw):
  147.         global d
  148.         mainwind = mw
  149.         mainwind.addstr("Initializing...")
  150.         mainwind.refresh()
  151.         curses.init_pair(1, curses.COLOR_RED, curses.COLOR_BLACK)
  152.         mainwind.erase()
  153.         height, width = mainwind.getmaxyx()
  154.         if height < 24 or width < 110:
  155.                 return 1
  156.         currdir = dir.getcwd()
  157.         #set up pretty view
  158.         mainwind.box()
  159.         mainwind.hline(2, 0, curses.ACS_HLINE, width)
  160.         mainwind.addch(2, 0, curses.ACS_LTEE)
  161.         mainwind.addch(2, width-1, curses.ACS_RTEE)
  162.         mainwind.hline(height-3, 0, curses.ACS_HLINE, width)
  163.         mainwind.addch(height-3, 0, curses.ACS_LTEE)
  164.         mainwind.addch(height-3, width-1, curses.ACS_RTEE)
  165.         mainwind.move(height-2, 1)
  166.         mainwind.addstr("Commands: q: quit, c: chdir, u: up, s: show/hide info window, i: show/hide invisible files, d: delete file")
  167.         infowind = curses.newwin(10, 50, 5, width-54)
  168.         d.info = False
  169.         d.invisible = True
  170.         setupdir(mainwind, infowind, width, height, currdir)
  171.         dirty = False
  172.         while True:
  173.                 mainwind.move(0, 0)
  174.                 c = mainwind.getch()
  175.                 if dirty == True:
  176.                         drawbottom(mainwind, width, height, "Commands: q: quit, c: chdir, u: up, s: show/hide info window, i: show/hide invisible files, d: delete file")
  177.                         dirty = False
  178.                 if c >= 0 and c < 256:
  179.                         c = chr(c)
  180.                 if c == "q":
  181.                         return
  182.                 elif c == curses.KEY_UP:
  183.                         if d.selected > 0:
  184.                                 d.oldselected = d.selected
  185.                                 d.selected = d.selected - 1
  186.                                 if d.selected < d.scroll:
  187.                                         d.scroll -= (height-6)/2
  188.                                 drawdir(mainwind, infowind, width, height)
  189.                 elif c == curses.KEY_DOWN:
  190.                         if d.selected < len(d.l)-1:
  191.                                 d.oldselected = d.selected
  192.                                 d.selected = d.selected + 1
  193.                                 if d.selected > d.scroll + height - 6:
  194.                                         d.scroll += (height-6)/2
  195.                                 if d.scroll > len(d.l)-height+6:
  196.                                         d.scroll = len(d.l)-height+6
  197.                                 drawdir(mainwind, infowind, width, height)
  198.                 elif c == "u":
  199.                         try:
  200.                                 dir.chdir("..")
  201.                         except OSError as e:
  202.                                 drawbottom(mainwind, width, height, "CHDir error: " + e[1] + " (" + str(e[0]) + ")")
  203.                                 dirty = True
  204.                                 continue
  205.                         currdir = dir.getcwd()
  206.                         setupdir(mainwind, infowind, width, height, currdir)
  207.                 elif c == "c":
  208.                         if d.i[d.l[d.selected]] != 1:
  209.                                 drawbottom(mainwind, width, height, "Error: Not a directory!")
  210.                                 dirty = True
  211.                         else:
  212.                                 try:
  213.                                         dir.chdir(d.l[d.selected])
  214.                                 except OSError as e:
  215.                                         drawbottom(mainwind, width, height, "CHDir error: " + e[1] + " (" + str(e[0]) + ")")
  216.                                         dirty = True
  217.                                         continue
  218.                                 currdir = dir.getcwd()
  219.                                 setupdir(mainwind, infowind, width, height, currdir)
  220.                 elif c == "s":
  221.                         if d.info == True:
  222.                                 d.info = False
  223.                                 mainwind.touchwin()
  224.                                 mainwind.refresh()
  225.                                 drawdir(mainwind, infowind, width, height)
  226.                         else:
  227.                                 d.info = True
  228.                                 drawdir(mainwind, infowind, width, height)
  229.                 elif c == "i":
  230.                         d.invisible = not d.invisible
  231.                         setupdir(mainwind, infowind, width, height, currdir)
  232.                 elif c == "d":
  233.                         dirty = True
  234.                         if d.i[d.l[d.selected]] != 0:
  235.                                 drawbottom(mainwind, width, height, "Error: Not a file!")
  236.                                 continue
  237.                         drawbottom(mainwind, width, height, "Are you sure? ")
  238.                         yn = mainwind.getch()
  239.                         if yn != ord("y"):
  240.                                 drawbottom(mainwind, width, height, "File deletion aborted!")
  241.                                 continue
  242.                         try:
  243.                                 os.unlink(d.l[d.selected])
  244.                                 setupdir(mainwind, infowind, width, height, currdir)
  245.                                 drawbottom(mainwind, width, height, "File deleted successfully!")
  246.                         except OSError as e:
  247.                                 drawbottom(mainwind, width, height, "Deletion error: " + e[1] + " (" + str(e[0]) + ")")
  248.                
  249. dir = CwdKeeper()
  250. d = Container()
  251. r = wrapper(main)
  252. if r == 1:
  253.         print "Your terminal isn't big enough! It needs to be at least 110x24."