mirror of
				https://github.com/python/cpython.git
				synced 2025-11-04 03:44:55 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			285 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
			
		
		
	
	
			285 lines
		
	
	
	
		
			6.4 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable file
		
	
	
	
	
#! /usr/local/bin/python
 | 
						|
 | 
						|
# Scan MH folder, display results in window
 | 
						|
 | 
						|
import os
 | 
						|
import sys
 | 
						|
import regex
 | 
						|
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 = regex.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(`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()
 |