home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / pyos2bin.zip / Demo / tkinter / guido / mbox.py < prev    next >
Text File  |  1996-11-27  |  7KB  |  286 lines

  1. #! /usr/bin/env python
  2.  
  3. # Scan MH folder, display results in window
  4.  
  5. import os
  6. import sys
  7. import regex
  8. import getopt
  9. import string
  10. import mhlib
  11.  
  12. from Tkinter import *
  13.  
  14. from dialog import dialog
  15.  
  16. mailbox = os.environ['HOME'] + '/Mail'
  17.  
  18. def main():
  19.     global root, tk, top, mid, bot
  20.     global folderbox, foldermenu, scanbox, scanmenu, viewer
  21.     global folder, seq
  22.     global mh, mhf
  23.  
  24.     # Parse command line options
  25.  
  26.     folder = 'inbox'
  27.     seq = 'all'
  28.     try:
  29.         opts, args = getopt.getopt(sys.argv[1:], '')
  30.     except getopt.error, msg:
  31.         print msg
  32.         sys.exit(2)
  33.     for arg in args:
  34.         if arg[:1] == '+':
  35.             folder = arg[1:]
  36.         else:
  37.             seq = arg
  38.  
  39.     # Initialize MH
  40.  
  41.     mh = mhlib.MH()
  42.     mhf = mh.openfolder(folder)
  43.  
  44.     # Build widget hierarchy
  45.  
  46.     root = Tk()
  47.     tk = root.tk
  48.  
  49.     top = Frame(root)
  50.     top.pack({'expand': 1, 'fill': 'both'})
  51.  
  52.     # Build right part: folder list
  53.  
  54.     right = Frame(top)
  55.     right.pack({'fill': 'y', 'side': 'right'})
  56.  
  57.     folderbar = Scrollbar(right, {'relief': 'sunken', 'bd': 2})
  58.     folderbar.pack({'fill': 'y', 'side': 'right'})
  59.  
  60.     folderbox = Listbox(right, {'exportselection': 0})
  61.     folderbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
  62.  
  63.     foldermenu = Menu(root)
  64.     foldermenu.add('command',
  65.                {'label': 'Open Folder',
  66.             'command': open_folder})
  67.     foldermenu.add('separator')
  68.     foldermenu.add('command',
  69.                {'label': 'Quit',
  70.             'command': 'exit'})
  71.     foldermenu.bind('<ButtonRelease-3>', folder_unpost)
  72.  
  73.     folderbox['yscrollcommand'] = (folderbar, 'set')
  74.     folderbar['command'] = (folderbox, 'yview')
  75.     folderbox.bind('<Double-1>', open_folder, 1)
  76.     folderbox.bind('<3>', folder_post)
  77.  
  78.     # Build left part: scan list
  79.  
  80.     left = Frame(top)
  81.     left.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
  82.  
  83.     scanbar = Scrollbar(left, {'relief': 'sunken', 'bd': 2})
  84.     scanbar.pack({'fill': 'y', 'side': 'right'})
  85.  
  86.     scanbox = Listbox(left, {'font': 'fixed'})
  87.     scanbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
  88.  
  89.     scanmenu = Menu(root)
  90.     scanmenu.add('command',
  91.              {'label': 'Open Message',
  92.               'command': open_message})
  93.     scanmenu.add('command',
  94.              {'label': 'Remove Message',
  95.               'command': remove_message})
  96.     scanmenu.add('command',
  97.              {'label': 'Refile Message',
  98.               'command': refile_message})
  99.     scanmenu.add('separator')
  100.     scanmenu.add('command',
  101.              {'label': 'Quit',
  102.               'command': 'exit'})
  103.     scanmenu.bind('<ButtonRelease-3>', scan_unpost)
  104.  
  105.     scanbox['yscrollcommand'] = (scanbar, 'set')
  106.     scanbar['command'] = (scanbox, 'yview')
  107.     scanbox.bind('<Double-1>', open_message)
  108.     scanbox.bind('<3>', scan_post)
  109.  
  110.     # Separator between middle and bottom part
  111.  
  112.     rule2 = Frame(root, {'bg': 'black'})
  113.     rule2.pack({'fill': 'x'})
  114.  
  115.     # Build bottom part: current message
  116.  
  117.     bot = Frame(root)
  118.     bot.pack({'expand': 1, 'fill': 'both'})
  119.     #
  120.     viewer = None
  121.  
  122.     # Window manager commands
  123.  
  124.     root.minsize(800, 1) # Make window resizable
  125.  
  126.     # Fill folderbox with text
  127.  
  128.     setfolders()
  129.  
  130.     # Fill scanbox with text
  131.  
  132.     rescan()
  133.  
  134.     # Enter mainloop
  135.  
  136.     root.mainloop()
  137.  
  138. def folder_post(e):
  139.     x, y = e.x_root, e.y_root
  140.     foldermenu.post(x - 10, y - 10)
  141.     foldermenu.grab_set()
  142.  
  143. def folder_unpost(e):
  144.     tk.call('update', 'idletasks')
  145.     foldermenu.grab_release()
  146.     foldermenu.unpost()
  147.     foldermenu.invoke('active')
  148.  
  149. def scan_post(e):
  150.     x, y = e.x_root, e.y_root
  151.     scanmenu.post(x - 10, y - 10)
  152.     scanmenu.grab_set()
  153.  
  154. def scan_unpost(e):
  155.     tk.call('update', 'idletasks')
  156.     scanmenu.grab_release()
  157.     scanmenu.unpost()
  158.     scanmenu.invoke('active')
  159.  
  160. scanparser = regex.compile('^ *\([0-9]+\)')
  161.  
  162. def open_folder(e=None):
  163.     global folder, mhf
  164.     sel = folderbox.curselection()
  165.     if len(sel) != 1:
  166.         if len(sel) > 1:
  167.             msg = "Please open one folder at a time"
  168.         else:
  169.             msg = "Please select a folder to open"
  170.         dialog(root, "Can't Open Folder", msg, "", 0, "OK")
  171.         return
  172.     i = sel[0]
  173.     folder = folderbox.get(i)
  174.     mhf = mh.openfolder(folder)
  175.     rescan()
  176.  
  177. def open_message(e=None):
  178.     global viewer
  179.     sel = scanbox.curselection()
  180.     if len(sel) != 1:
  181.         if len(sel) > 1:
  182.             msg = "Please open one message at a time"
  183.         else:
  184.             msg = "Please select a message to open"
  185.         dialog(root, "Can't Open Message", msg, "", 0, "OK")
  186.         return
  187.     cursor = scanbox['cursor']
  188.     scanbox['cursor'] = 'watch'
  189.     tk.call('update', 'idletasks')
  190.     i = sel[0]
  191.     line = scanbox.get(i)
  192.     if scanparser.match(line) >= 0:
  193.         num = string.atoi(scanparser.group(1))
  194.         m = mhf.openmessage(num)
  195.         if viewer: viewer.destroy()
  196.         from MimeViewer import MimeViewer
  197.         viewer = MimeViewer(bot, '+%s/%d' % (folder, num), m)
  198.         viewer.pack()
  199.         viewer.show()
  200.     scanbox['cursor'] = cursor
  201.  
  202. def interestingheader(header):
  203.     return header != 'received'
  204.  
  205. def remove_message(e=None):
  206.     itop = scanbox.nearest(0)
  207.     sel = scanbox.curselection()
  208.     if not sel:
  209.         dialog(root, "No Message To Remove",
  210.                "Please select a message to remove", "", 0, "OK")
  211.         return
  212.     todo = []
  213.     for i in sel:
  214.         line = scanbox.get(i)
  215.         if scanparser.match(line) >= 0:
  216.             todo.append(string.atoi(scanparser.group(1)))
  217.     mhf.removemessages(todo)
  218.     rescan()
  219.     fixfocus(min(todo), itop)
  220.  
  221. lastrefile = ''
  222. tofolder = None
  223. def refile_message(e=None):
  224.     global lastrefile, tofolder
  225.     itop = scanbox.nearest(0)
  226.     sel = scanbox.curselection()
  227.     if not sel:
  228.         dialog(root, "No Message To Refile",
  229.                "Please select a message to refile", "", 0, "OK")
  230.         return
  231.     foldersel = folderbox.curselection()
  232.     if len(foldersel) != 1:
  233.         if not foldersel:
  234.             msg = "Please select a folder to refile to"
  235.         else:
  236.             msg = "Please select exactly one folder to refile to"
  237.         dialog(root, "No Folder To Refile", msg, "", 0, "OK")
  238.         return
  239.     refileto = folderbox.get(foldersel[0])
  240.     todo = []
  241.     for i in sel:
  242.         line = scanbox.get(i)
  243.         if scanparser.match(line) >= 0:
  244.             todo.append(string.atoi(scanparser.group(1)))
  245.     if lastrefile != refileto or not tofolder:
  246.         lastrefile = refileto
  247.         tofolder = None
  248.         tofolder = mh.openfolder(lastrefile)
  249.     mhf.refilemessages(todo, tofolder)
  250.     rescan()
  251.     fixfocus(min(todo), itop)
  252.  
  253. def fixfocus(near, itop):
  254.     n = scanbox.size()
  255.     for i in range(n):
  256.         line = scanbox.get(`i`)
  257.         if scanparser.match(line) >= 0:
  258.             num = string.atoi(scanparser.group(1))
  259.             if num >= near:
  260.                 break
  261.     else:
  262.         i = 'end'
  263.     scanbox.select_from(i)
  264.     scanbox.yview(itop)
  265.  
  266. def setfolders():
  267.     folderbox.delete(0, 'end')
  268.     for fn in mh.listallfolders():
  269.         folderbox.insert('end', fn)
  270.  
  271. def rescan():
  272.     global viewer
  273.     if viewer:
  274.         viewer.destroy()
  275.         viewer = None
  276.     scanbox.delete(0, 'end')
  277.     for line in scanfolder(folder, seq):
  278.         scanbox.insert('end', line)
  279.  
  280. def scanfolder(folder = 'inbox', sequence = 'all'):
  281.     return map(
  282.         lambda line: line[:-1],
  283.         os.popen('scan +%s %s' % (folder, sequence), 'r').readlines())
  284.  
  285. main()
  286.