mirror of
				https://github.com/python/cpython.git
				synced 2025-11-03 23:21:29 +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()
 |