mirror of
				https://github.com/python/cpython.git
				synced 2025-10-31 10:26:02 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			285 lines
		
	
	
	
		
			7.3 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
	
		
			7.3 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
| #! /usr/bin/env python
 | |
| 
 | |
| # Scan MH folder, display results in window
 | |
| 
 | |
| import os
 | |
| import sys
 | |
| import re
 | |
| import getopt
 | |
| import string
 | |
| import mhlib
 | |
| 
 | |
| from Tkinter import *
 | |
| 
 | |
| from dialog import dialog
 | |
| 
 | |
| mailbox = os.environ['HOME'] + '/Mail'
 | |
| 
 | |
| def main():
 | |
|     global root, tk, top, mid, bot
 | |
|     global folderbox, foldermenu, scanbox, scanmenu, viewer
 | |
|     global folder, seq
 | |
|     global mh, mhf
 | |
| 
 | |
|     # Parse command line options
 | |
| 
 | |
|     folder = 'inbox'
 | |
|     seq = 'all'
 | |
|     try:
 | |
|         opts, args = getopt.getopt(sys.argv[1:], '')
 | |
|     except getopt.error, msg:
 | |
|         print msg
 | |
|         sys.exit(2)
 | |
|     for arg in args:
 | |
|         if arg[:1] == '+':
 | |
|             folder = arg[1:]
 | |
|         else:
 | |
|             seq = arg
 | |
| 
 | |
|     # Initialize MH
 | |
| 
 | |
|     mh = mhlib.MH()
 | |
|     mhf = mh.openfolder(folder)
 | |
| 
 | |
|     # Build widget hierarchy
 | |
| 
 | |
|     root = Tk()
 | |
|     tk = root.tk
 | |
| 
 | |
|     top = Frame(root)
 | |
|     top.pack({'expand': 1, 'fill': 'both'})
 | |
| 
 | |
|     # Build right part: folder list
 | |
| 
 | |
|     right = Frame(top)
 | |
|     right.pack({'fill': 'y', 'side': 'right'})
 | |
| 
 | |
|     folderbar = Scrollbar(right, {'relief': 'sunken', 'bd': 2})
 | |
|     folderbar.pack({'fill': 'y', 'side': 'right'})
 | |
| 
 | |
|     folderbox = Listbox(right, {'exportselection': 0})
 | |
|     folderbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
 | |
| 
 | |
|     foldermenu = Menu(root)
 | |
|     foldermenu.add('command',
 | |
|                    {'label': 'Open Folder',
 | |
|                     'command': open_folder})
 | |
|     foldermenu.add('separator')
 | |
|     foldermenu.add('command',
 | |
|                    {'label': 'Quit',
 | |
|                     'command': 'exit'})
 | |
|     foldermenu.bind('<ButtonRelease-3>', folder_unpost)
 | |
| 
 | |
|     folderbox['yscrollcommand'] = (folderbar, 'set')
 | |
|     folderbar['command'] = (folderbox, 'yview')
 | |
|     folderbox.bind('<Double-1>', open_folder, 1)
 | |
|     folderbox.bind('<3>', folder_post)
 | |
| 
 | |
|     # Build left part: scan list
 | |
| 
 | |
|     left = Frame(top)
 | |
|     left.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
 | |
| 
 | |
|     scanbar = Scrollbar(left, {'relief': 'sunken', 'bd': 2})
 | |
|     scanbar.pack({'fill': 'y', 'side': 'right'})
 | |
| 
 | |
|     scanbox = Listbox(left, {'font': 'fixed'})
 | |
|     scanbox.pack({'expand': 1, 'fill': 'both', 'side': 'left'})
 | |
| 
 | |
|     scanmenu = Menu(root)
 | |
|     scanmenu.add('command',
 | |
|                  {'label': 'Open Message',
 | |
|                   'command': open_message})
 | |
|     scanmenu.add('command',
 | |
|                  {'label': 'Remove Message',
 | |
|                   'command': remove_message})
 | |
|     scanmenu.add('command',
 | |
|                  {'label': 'Refile Message',
 | |
|                   'command': refile_message})
 | |
|     scanmenu.add('separator')
 | |
|     scanmenu.add('command',
 | |
|                  {'label': 'Quit',
 | |
|                   'command': 'exit'})
 | |
|     scanmenu.bind('<ButtonRelease-3>', scan_unpost)
 | |
| 
 | |
|     scanbox['yscrollcommand'] = (scanbar, 'set')
 | |
|     scanbar['command'] = (scanbox, 'yview')
 | |
|     scanbox.bind('<Double-1>', open_message)
 | |
|     scanbox.bind('<3>', scan_post)
 | |
| 
 | |
|     # Separator between middle and bottom part
 | |
| 
 | |
|     rule2 = Frame(root, {'bg': 'black'})
 | |
|     rule2.pack({'fill': 'x'})
 | |
| 
 | |
|     # Build bottom part: current message
 | |
| 
 | |
|     bot = Frame(root)
 | |
|     bot.pack({'expand': 1, 'fill': 'both'})
 | |
|     #
 | |
|     viewer = None
 | |
| 
 | |
|     # Window manager commands
 | |
| 
 | |
|     root.minsize(800, 1) # Make window resizable
 | |
| 
 | |
|     # Fill folderbox with text
 | |
| 
 | |
|     setfolders()
 | |
| 
 | |
|     # Fill scanbox with text
 | |
| 
 | |
|     rescan()
 | |
| 
 | |
|     # Enter mainloop
 | |
| 
 | |
|     root.mainloop()
 | |
| 
 | |
| def folder_post(e):
 | |
|     x, y = e.x_root, e.y_root
 | |
|     foldermenu.post(x - 10, y - 10)
 | |
|     foldermenu.grab_set()
 | |
| 
 | |
| def folder_unpost(e):
 | |
|     tk.call('update', 'idletasks')
 | |
|     foldermenu.grab_release()
 | |
|     foldermenu.unpost()
 | |
|     foldermenu.invoke('active')
 | |
| 
 | |
| def scan_post(e):
 | |
|     x, y = e.x_root, e.y_root
 | |
|     scanmenu.post(x - 10, y - 10)
 | |
|     scanmenu.grab_set()
 | |
| 
 | |
| def scan_unpost(e):
 | |
|     tk.call('update', 'idletasks')
 | |
|     scanmenu.grab_release()
 | |
|     scanmenu.unpost()
 | |
|     scanmenu.invoke('active')
 | |
| 
 | |
| scanparser = re.compile('^ *([0-9]+)')
 | |
| 
 | |
| def open_folder(e=None):
 | |
|     global folder, mhf
 | |
|     sel = folderbox.curselection()
 | |
|     if len(sel) != 1:
 | |
|         if len(sel) > 1:
 | |
|             msg = "Please open one folder at a time"
 | |
|         else:
 | |
|             msg = "Please select a folder to open"
 | |
|         dialog(root, "Can't Open Folder", msg, "", 0, "OK")
 | |
|         return
 | |
|     i = sel[0]
 | |
|     folder = folderbox.get(i)
 | |
|     mhf = mh.openfolder(folder)
 | |
|     rescan()
 | |
| 
 | |
| def open_message(e=None):
 | |
|     global viewer
 | |
|     sel = scanbox.curselection()
 | |
|     if len(sel) != 1:
 | |
|         if len(sel) > 1:
 | |
|             msg = "Please open one message at a time"
 | |
|         else:
 | |
|             msg = "Please select a message to open"
 | |
|         dialog(root, "Can't Open Message", msg, "", 0, "OK")
 | |
|         return
 | |
|     cursor = scanbox['cursor']
 | |
|     scanbox['cursor'] = 'watch'
 | |
|     tk.call('update', 'idletasks')
 | |
|     i = sel[0]
 | |
|     line = scanbox.get(i)
 | |
|     if scanparser.match(line) >= 0:
 | |
|         num = string.atoi(scanparser.group(1))
 | |
|         m = mhf.openmessage(num)
 | |
|         if viewer: viewer.destroy()
 | |
|         from MimeViewer import MimeViewer
 | |
|         viewer = MimeViewer(bot, '+%s/%d' % (folder, num), m)
 | |
|         viewer.pack()
 | |
|         viewer.show()
 | |
|     scanbox['cursor'] = cursor
 | |
| 
 | |
| def interestingheader(header):
 | |
|     return header != 'received'
 | |
| 
 | |
| def remove_message(e=None):
 | |
|     itop = scanbox.nearest(0)
 | |
|     sel = scanbox.curselection()
 | |
|     if not sel:
 | |
|         dialog(root, "No Message To Remove",
 | |
|                "Please select a message to remove", "", 0, "OK")
 | |
|         return
 | |
|     todo = []
 | |
|     for i in sel:
 | |
|         line = scanbox.get(i)
 | |
|         if scanparser.match(line) >= 0:
 | |
|             todo.append(string.atoi(scanparser.group(1)))
 | |
|     mhf.removemessages(todo)
 | |
|     rescan()
 | |
|     fixfocus(min(todo), itop)
 | |
| 
 | |
| lastrefile = ''
 | |
| tofolder = None
 | |
| def refile_message(e=None):
 | |
|     global lastrefile, tofolder
 | |
|     itop = scanbox.nearest(0)
 | |
|     sel = scanbox.curselection()
 | |
|     if not sel:
 | |
|         dialog(root, "No Message To Refile",
 | |
|                "Please select a message to refile", "", 0, "OK")
 | |
|         return
 | |
|     foldersel = folderbox.curselection()
 | |
|     if len(foldersel) != 1:
 | |
|         if not foldersel:
 | |
|             msg = "Please select a folder to refile to"
 | |
|         else:
 | |
|             msg = "Please select exactly one folder to refile to"
 | |
|         dialog(root, "No Folder To Refile", msg, "", 0, "OK")
 | |
|         return
 | |
|     refileto = folderbox.get(foldersel[0])
 | |
|     todo = []
 | |
|     for i in sel:
 | |
|         line = scanbox.get(i)
 | |
|         if scanparser.match(line) >= 0:
 | |
|             todo.append(string.atoi(scanparser.group(1)))
 | |
|     if lastrefile != refileto or not tofolder:
 | |
|         lastrefile = refileto
 | |
|         tofolder = None
 | |
|         tofolder = mh.openfolder(lastrefile)
 | |
|     mhf.refilemessages(todo, tofolder)
 | |
|     rescan()
 | |
|     fixfocus(min(todo), itop)
 | |
| 
 | |
| def fixfocus(near, itop):
 | |
|     n = scanbox.size()
 | |
|     for i in range(n):
 | |
|         line = scanbox.get(repr(i))
 | |
|         if scanparser.match(line) >= 0:
 | |
|             num = string.atoi(scanparser.group(1))
 | |
|             if num >= near:
 | |
|                 break
 | |
|     else:
 | |
|         i = 'end'
 | |
|     scanbox.select_from(i)
 | |
|     scanbox.yview(itop)
 | |
| 
 | |
| def setfolders():
 | |
|     folderbox.delete(0, 'end')
 | |
|     for fn in mh.listallfolders():
 | |
|         folderbox.insert('end', fn)
 | |
| 
 | |
| def rescan():
 | |
|     global viewer
 | |
|     if viewer:
 | |
|         viewer.destroy()
 | |
|         viewer = None
 | |
|     scanbox.delete(0, 'end')
 | |
|     for line in scanfolder(folder, seq):
 | |
|         scanbox.insert('end', line)
 | |
| 
 | |
| def scanfolder(folder = 'inbox', sequence = 'all'):
 | |
|     return map(
 | |
|             lambda line: line[:-1],
 | |
|             os.popen('scan +%s %s' % (folder, sequence), 'r').readlines())
 | |
| 
 | |
| main()
 | 
