<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="it">
	<id>http://wiki.netsitech.com/index.php?action=history&amp;feed=atom&amp;title=Qui_il_codice</id>
	<title>Qui il codice - Cronologia</title>
	<link rel="self" type="application/atom+xml" href="http://wiki.netsitech.com/index.php?action=history&amp;feed=atom&amp;title=Qui_il_codice"/>
	<link rel="alternate" type="text/html" href="http://wiki.netsitech.com/index.php?title=Qui_il_codice&amp;action=history"/>
	<updated>2026-05-07T07:46:17Z</updated>
	<subtitle>Cronologia della pagina su questo sito</subtitle>
	<generator>MediaWiki 1.34.4</generator>
	<entry>
		<id>http://wiki.netsitech.com/index.php?title=Qui_il_codice&amp;diff=9322&amp;oldid=prev</id>
		<title>Mazzotti: Creata pagina con &quot;&lt;syntaxhighlight lang=&quot;python&quot;&gt; #!/usr/bin/python -tt # # Copyright 2004-2006 Nathaniel W. Turner &lt;nate@houseofnate.net&gt; # # Permission is hereby granted, free of charge, to a...&quot;</title>
		<link rel="alternate" type="text/html" href="http://wiki.netsitech.com/index.php?title=Qui_il_codice&amp;diff=9322&amp;oldid=prev"/>
		<updated>2016-02-26T16:43:51Z</updated>

		<summary type="html">&lt;p&gt;Creata pagina con &amp;quot;&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt; #!/usr/bin/python -tt # # Copyright 2004-2006 Nathaniel W. Turner &amp;lt;nate@houseofnate.net&amp;gt; # # Permission is hereby granted, free of charge, to a...&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Nuova pagina&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;lt;syntaxhighlight lang=&amp;quot;python&amp;quot;&amp;gt;&lt;br /&gt;
#!/usr/bin/python -tt&lt;br /&gt;
#&lt;br /&gt;
# Copyright 2004-2006 Nathaniel W. Turner &amp;lt;nate@houseofnate.net&amp;gt;&lt;br /&gt;
#&lt;br /&gt;
# Permission is hereby granted, free of charge, to any person&lt;br /&gt;
# obtaining a copy of this software and associated documentation&lt;br /&gt;
# files (the &amp;quot;Software&amp;quot;), to deal in the Software without&lt;br /&gt;
# restriction, including without limitation the rights to use,&lt;br /&gt;
# copy, modify, merge, publish, distribute, sublicense, and/or sell&lt;br /&gt;
# copies of the Software, and to permit persons to whom the&lt;br /&gt;
# Software is furnished to do so, subject to the following&lt;br /&gt;
# conditions:&lt;br /&gt;
#&lt;br /&gt;
# The above copyright notice and this permission notice shall be&lt;br /&gt;
# included in all copies or substantial portions of the Software.&lt;br /&gt;
#&lt;br /&gt;
# THE SOFTWARE IS PROVIDED &amp;quot;AS IS&amp;quot;, WITHOUT WARRANTY OF ANY KIND,&lt;br /&gt;
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES&lt;br /&gt;
# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND&lt;br /&gt;
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT&lt;br /&gt;
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,&lt;br /&gt;
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING&lt;br /&gt;
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR&lt;br /&gt;
# OTHER DEALINGS IN THE SOFTWARE.&lt;br /&gt;
&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
USAGE&lt;br /&gt;
  cleanup-maildir [OPTION].. COMMAND FOLDERNAME..&lt;br /&gt;
&lt;br /&gt;
DESCRIPTION&lt;br /&gt;
  Cleans up old messages in FOLDERNAME; the exact action taken&lt;br /&gt;
  depends on COMMAND.  (See next section.)&lt;br /&gt;
      Note that FOLDERNAME is a name such as 'Drafts', and the&lt;br /&gt;
  corresponding maildir path is determined using the values of&lt;br /&gt;
  maildir-root, folder-prefix, and folder-seperator.&lt;br /&gt;
&lt;br /&gt;
COMMANDS&lt;br /&gt;
  archive - move old messages to subfolders based on message date&lt;br /&gt;
  trash   - move old message to trash folder&lt;br /&gt;
  delete  - permanently delete old messages&lt;br /&gt;
&lt;br /&gt;
OPTIONS&lt;br /&gt;
  -h, --help&lt;br /&gt;
      Show this help.&lt;br /&gt;
  -q, --quiet&lt;br /&gt;
      Suppress normal output.&lt;br /&gt;
  -v, --verbose&lt;br /&gt;
      Output extra information for testing.&lt;br /&gt;
  -n, --trial-run&lt;br /&gt;
      Do not actually touch any files; just say what would be done.&lt;br /&gt;
  -a, --age=N&lt;br /&gt;
      Only touch messages older than N days.  Default is 14 days.&lt;br /&gt;
  -k, --keep-flagged-threads&lt;br /&gt;
      If any messages in a thread are flagged, do not touch them or&lt;br /&gt;
      any other messages in that thread.&lt;br /&gt;
      Note: the thread-detection mechanism is currently base purely on&lt;br /&gt;
      a message's subject.  The In-Reply-To header is not currently used.&lt;br /&gt;
  -r, --keep-read&lt;br /&gt;
      If any messages are flagged as READ, do not touch them.&lt;br /&gt;
  -t, --trash-folder=F&lt;br /&gt;
      Use F as trash folder when COMMAND is 'trash'.&lt;br /&gt;
      Default is 'Trash'.&lt;br /&gt;
  --archive-folder=F&lt;br /&gt;
      Use F as the base for constructing archive folders.  For example, if F is&lt;br /&gt;
      'Archive', messages from 2004 might be put in the folder 'Archive.2004'.&lt;br /&gt;
  -d, --archive-hierarchy-depth=N&lt;br /&gt;
      Specify number of subfolders in archive hierarchy; 1 is just&lt;br /&gt;
      the year, 2 is year/month (default), 3 is year/month/day.&lt;br /&gt;
  --maildir-root=F&lt;br /&gt;
      Specifies folder that contains mail folders.&lt;br /&gt;
      Default is &amp;quot;$HOME/Maildir&amp;quot;.&lt;br /&gt;
  --folder-seperator=str&lt;br /&gt;
      Folder hierarchy seperator.  Default is '.'&lt;br /&gt;
  --folder-prefix=str&lt;br /&gt;
      Folder prefix.  Default is '.'&lt;br /&gt;
&lt;br /&gt;
NOTES&lt;br /&gt;
  The following form is accepted for backwards compatibility, but is deprecated:&lt;br /&gt;
  cleanup-maildir --mode=COMMAND [OPTION].. FOLDERNAME..&lt;br /&gt;
&lt;br /&gt;
EXAMPLES&lt;br /&gt;
  # Archive messages in 'Sent Items' folder over 30 days old&lt;br /&gt;
  cleanup-maildir --age=30 archive 'Sent Items'&amp;quot; &lt;br /&gt;
&lt;br /&gt;
  # Delete messages over 2 weeks old in 'Lists/debian-devel' folder,&lt;br /&gt;
  # except messages that are part of a thread containing a flagged message.&lt;br /&gt;
  cleanup-maildir --keep-flagged-threads trash 'Lists.debian-devel'&lt;br /&gt;
&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
__version__ = &amp;quot;0.3.0&amp;quot;&lt;br /&gt;
# $Id$&lt;br /&gt;
# $URL$&lt;br /&gt;
&lt;br /&gt;
import mailbox&lt;br /&gt;
import os.path&lt;br /&gt;
import os&lt;br /&gt;
import rfc822&lt;br /&gt;
import string&lt;br /&gt;
import socket&lt;br /&gt;
import time&lt;br /&gt;
import logging&lt;br /&gt;
import sys&lt;br /&gt;
import getopt&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
def mkMaildir(path):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Make a Maildir structure rooted at 'path'&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    os.mkdir(path, 0700)&lt;br /&gt;
    os.mkdir(os.path.join(path, 'tmp'), 0700)&lt;br /&gt;
    os.mkdir(os.path.join(path, 'new'), 0700)&lt;br /&gt;
    os.mkdir(os.path.join(path, 'cur'), 0700)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class MaildirWriter(object):&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Deliver messages into a Maildir&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    path = None&lt;br /&gt;
    counter = 0&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, path=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Create a MaildirWriter that manages the Maildir at 'path'&lt;br /&gt;
&lt;br /&gt;
        Arguments:&lt;br /&gt;
        path -- if specified, used as the default Maildir for this object&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if path != None:&lt;br /&gt;
            if not os.path.isdir(path):&lt;br /&gt;
                raise ValueError, 'Path does not exist: %s' % path&lt;br /&gt;
            self.path = path&lt;br /&gt;
        self.logger = logging.getLogger('MaildirWriter')&lt;br /&gt;
&lt;br /&gt;
    def deliver(self, msg, path=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Deliver a message to a Maildir&lt;br /&gt;
&lt;br /&gt;
        Arguments:&lt;br /&gt;
        msg -- a message object&lt;br /&gt;
        path -- the path of the Maildir; if None, uses default from __init__&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        if path != None:&lt;br /&gt;
            self.path = path&lt;br /&gt;
        if self.path == None or not os.path.isdir(self.path):&lt;br /&gt;
            raise ValueError, 'Path does not exist'&lt;br /&gt;
        tryCount = 1&lt;br /&gt;
        srcFile = msg.getFilePath();&lt;br /&gt;
        (dstName, tmpFile, newFile, dstFile) = (None, None, None, None)&lt;br /&gt;
        while 1:&lt;br /&gt;
            try:&lt;br /&gt;
                dstName = &amp;quot;%d.%d_%d.%s&amp;quot; % (int(time.time()), os.getpid(), &lt;br /&gt;
                                           self.counter, socket.gethostname())&lt;br /&gt;
                tmpFile = os.path.join(os.path.join(self.path, &amp;quot;tmp&amp;quot;), dstName)&lt;br /&gt;
                newFile = os.path.join(os.path.join(self.path, &amp;quot;new&amp;quot;), dstName)&lt;br /&gt;
                self.logger.debug(&amp;quot;deliver: attempt copy %s to %s&amp;quot; %&lt;br /&gt;
                              (srcFile, tmpFile))&lt;br /&gt;
                os.link(srcFile, tmpFile) # Copy into tmp&lt;br /&gt;
                self.logger.debug(&amp;quot;deliver: attempt link to %s&amp;quot; % newFile)&lt;br /&gt;
                os.link(tmpFile, newFile) # Link into new&lt;br /&gt;
            except OSError, (n, s):&lt;br /&gt;
                self.logger.critical(&lt;br /&gt;
                        &amp;quot;deliver failed: %s (src=%s tmp=%s new=%s i=%d)&amp;quot; % &lt;br /&gt;
                        (s, srcFile, tmpFile, newFile, tryCount))&lt;br /&gt;
                self.logger.info(&amp;quot;sleeping&amp;quot;)&lt;br /&gt;
                time.sleep(2)&lt;br /&gt;
                tryCount += 1&lt;br /&gt;
                self.counter += 1&lt;br /&gt;
                if tryCount &amp;gt; 10:&lt;br /&gt;
                    raise OSError(&amp;quot;too many failed delivery attempts&amp;quot;)&lt;br /&gt;
            else:&lt;br /&gt;
                break&lt;br /&gt;
&lt;br /&gt;
        # Successful delivery; increment deliver counter&lt;br /&gt;
        self.counter += 1&lt;br /&gt;
&lt;br /&gt;
        # For the rest of this method we are acting as an MUA, not an MDA.&lt;br /&gt;
&lt;br /&gt;
        # Move message to cur and restore any flags&lt;br /&gt;
        dstFile = os.path.join(os.path.join(self.path, &amp;quot;cur&amp;quot;), dstName)&lt;br /&gt;
        if msg.getFlags() != None:&lt;br /&gt;
            dstFile += ':' + msg.getFlags()&lt;br /&gt;
        self.logger.debug(&amp;quot;deliver: attempt link to %s&amp;quot; % dstFile)&lt;br /&gt;
        os.link(newFile, dstFile)&lt;br /&gt;
        os.unlink(newFile)&lt;br /&gt;
&lt;br /&gt;
        # Cleanup tmp file&lt;br /&gt;
        os.unlink(tmpFile)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class MessageDateError(TypeError):&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Indicate that the message date was invalid&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
    pass&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class MaildirMessage(rfc822.Message):&lt;br /&gt;
    &lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;An email message&lt;br /&gt;
&lt;br /&gt;
    Has extra Maildir-specific attributes&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    def getFilePath(self):&lt;br /&gt;
        if sys.hexversion &amp;gt;= 0x020500F0:&lt;br /&gt;
            return self.fp._file.name&lt;br /&gt;
        else:&lt;br /&gt;
            return self.fp.name&lt;br /&gt;
&lt;br /&gt;
    def isFlagged(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;return true if the message is flagged as important&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        import re&lt;br /&gt;
        fname = self.getFilePath()&lt;br /&gt;
        if re.search(r':.*F', fname) != None:&lt;br /&gt;
            return True&lt;br /&gt;
        return False&lt;br /&gt;
&lt;br /&gt;
    def getFlags(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;return the flag part of the message's filename&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        parts = self.getFilePath().split(':')&lt;br /&gt;
        if len(parts) == 2:&lt;br /&gt;
            return parts[1]&lt;br /&gt;
        return None&lt;br /&gt;
&lt;br /&gt;
    def isNew(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;return true if the message is marked as unread&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        # XXX should really be called isUnread&lt;br /&gt;
        import re&lt;br /&gt;
        fname = self.getFilePath()&lt;br /&gt;
        if re.search(r':.*S', fname) != None:&lt;br /&gt;
            return False&lt;br /&gt;
        return True&lt;br /&gt;
&lt;br /&gt;
    def getSubject(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;get the message's subject as a unicode string&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        import email.Header&lt;br /&gt;
        s = self.getheader(&amp;quot;Subject&amp;quot;)&lt;br /&gt;
        try:&lt;br /&gt;
            return u&amp;quot;&amp;quot;.join(map(lambda x: x[0].decode(x[1] or 'ASCII', 'replace'),&lt;br /&gt;
                                email.Header.decode_header(s)))&lt;br /&gt;
        except(LookupError):&lt;br /&gt;
            return s&lt;br /&gt;
&lt;br /&gt;
    def getSubjectHash(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;get the message's subject in a &amp;quot;normalized&amp;quot; form&lt;br /&gt;
&lt;br /&gt;
        This currently means lowercasing and removing any reply or forward&lt;br /&gt;
        indicators.&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        import re&lt;br /&gt;
        import string&lt;br /&gt;
        s = self.getSubject()&lt;br /&gt;
        if s == None:&lt;br /&gt;
            return '(no subject)'&lt;br /&gt;
        return re.sub(r'^(re|fwd?):\s*', '', string.strip(s.lower()))&lt;br /&gt;
&lt;br /&gt;
    def getDateSent(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Get the time of sending from the Date header&lt;br /&gt;
&lt;br /&gt;
        Returns a time object using time.mktime.  Not very reliable, because&lt;br /&gt;
        the Date header can be missing or spoofed (and often is, by spammers).&lt;br /&gt;
        Throws a MessageDateError if the Date header is missing or invalid.&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        dh = self.getheader('Date')&lt;br /&gt;
        if dh == None: &lt;br /&gt;
            return None&lt;br /&gt;
        try:&lt;br /&gt;
            return time.mktime(rfc822.parsedate(dh))&lt;br /&gt;
        except ValueError:&lt;br /&gt;
            raise MessageDateError(&amp;quot;message has missing or bad Date&amp;quot;)&lt;br /&gt;
        except TypeError:  # gets thrown by mktime if parsedate returns None&lt;br /&gt;
            raise MessageDateError(&amp;quot;message has missing or bad Date&amp;quot;)&lt;br /&gt;
        except OverflowError:&lt;br /&gt;
            raise MessageDateError(&amp;quot;message has missing or bad Date&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
    def getDateRecd(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Get the time the message was received&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        # XXX check that stat returns time in UTC, fix if not&lt;br /&gt;
        return os.stat(self.getFilePath())[8]&lt;br /&gt;
&lt;br /&gt;
    def getDateSentOrRecd(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Get the time the message was sent, fall back on time received&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        try:&lt;br /&gt;
            d = self.getDateSent()&lt;br /&gt;
            if d != None:&lt;br /&gt;
                return d&lt;br /&gt;
        except MessageDateError:&lt;br /&gt;
            pass&lt;br /&gt;
        return self.getDateRecd()&lt;br /&gt;
&lt;br /&gt;
    def getAge(self):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Get the number of seconds since the message was received&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        msgTime = self.getDateRecd()&lt;br /&gt;
        msgAge = time.mktime(time.gmtime()) - msgTime&lt;br /&gt;
        return msgAge / (60*60*24)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
class MaildirCleaner(object):&lt;br /&gt;
&lt;br /&gt;
    &amp;quot;&amp;quot;&amp;quot;Clean a maildir by deleting or moving old messages&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
    __trashWriter = None&lt;br /&gt;
    __mdWriter = None&lt;br /&gt;
    stats = {'total': 0, 'delete': 0, 'trash': 0, 'archive': 0}&lt;br /&gt;
    keepSubjects = {}&lt;br /&gt;
    archiveFolder = None&lt;br /&gt;
    archiveHierDepth = 2&lt;br /&gt;
    folderBase = None&lt;br /&gt;
    folderPrefix = &amp;quot;.&amp;quot;&lt;br /&gt;
    folderSeperator = &amp;quot;.&amp;quot;&lt;br /&gt;
    keepFlaggedThreads = False&lt;br /&gt;
    trashFolder = &amp;quot;Trash&amp;quot;&lt;br /&gt;
    isTrialRun = False&lt;br /&gt;
    keepRead = False&lt;br /&gt;
&lt;br /&gt;
    def __init__(self, folderBase=None):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Initialize the MaildirCleaner&lt;br /&gt;
&lt;br /&gt;
        Arguments:&lt;br /&gt;
        folderBase -- the directory in which the folders are found&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        self.folderBase = folderBase&lt;br /&gt;
        self.__mdWriter = MaildirWriter()&lt;br /&gt;
        self.logger = logging.getLogger('MaildirCleaner')&lt;br /&gt;
        self.logger.setLevel(logging.DEBUG)&lt;br /&gt;
&lt;br /&gt;
    def __getTrashWriter(self):&lt;br /&gt;
        if not self.__trashWriter:&lt;br /&gt;
            path = os.path.join(self.folderBase, self.folderPrefix + self.trashFolder)&lt;br /&gt;
            self.__trashWriter = MaildirWriter(path)&lt;br /&gt;
        return self.__trashWriter&lt;br /&gt;
&lt;br /&gt;
    trashWriter = property(__getTrashWriter)&lt;br /&gt;
&lt;br /&gt;
    def scanSubjects(self, folderName):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Scans for flagged subjects&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        self.logger.info(&amp;quot;Scanning for flagged subjects...&amp;quot;)&lt;br /&gt;
        if (folderName == 'INBOX'):&lt;br /&gt;
            path = self.folderBase&lt;br /&gt;
        else:&lt;br /&gt;
            path = os.path.join(self.folderBase, self.folderPrefix + folderName)&lt;br /&gt;
        maildir = mailbox.Maildir(path, MaildirMessage)&lt;br /&gt;
        self.keepSubjects = {}&lt;br /&gt;
        for i, msg in enumerate(maildir):&lt;br /&gt;
            if msg.isFlagged():&lt;br /&gt;
                self.keepSubjects[msg.getSubjectHash()] = 1&lt;br /&gt;
                self.logger.debug(&amp;quot;Flagged (%d): %s&amp;quot;, i, msg.getSubjectHash())&lt;br /&gt;
        self.logger.info(&amp;quot;Done scanning.&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    def clean(self, mode, folderName, minAge):&lt;br /&gt;
&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Trashes or archives messages older than minAge days&lt;br /&gt;
&lt;br /&gt;
        Arguments:&lt;br /&gt;
        mode -- the cleaning mode.  Valid modes are:&lt;br /&gt;
            trash -- moves the messages to a trash folder&lt;br /&gt;
            archive -- moves the messages to folders based on their date&lt;br /&gt;
            delete -- deletes the messages&lt;br /&gt;
        folderName -- the name of the folder on which to operate&lt;br /&gt;
            This is a name like &amp;quot;Stuff&amp;quot;, not a filename&lt;br /&gt;
        minAge -- messages younger than minAge days are left alone&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
&lt;br /&gt;
        if not mode in ('trash', 'archive', 'delete'):&lt;br /&gt;
            raise ValueError&lt;br /&gt;
&lt;br /&gt;
        if (self.keepFlaggedThreads):&lt;br /&gt;
            self.scanSubjects(folderName)&lt;br /&gt;
&lt;br /&gt;
        archiveFolder = self.archiveFolder&lt;br /&gt;
        if (archiveFolder == None):&lt;br /&gt;
            if (folderName == 'INBOX'):&lt;br /&gt;
                archiveFolder = &amp;quot;&amp;quot;&lt;br /&gt;
            else:&lt;br /&gt;
                archiveFolder = folderName&lt;br /&gt;
&lt;br /&gt;
        if (folderName == 'INBOX'):&lt;br /&gt;
            path = self.folderBase&lt;br /&gt;
        else:&lt;br /&gt;
            path = os.path.join(self.folderBase, self.folderPrefix + folderName)&lt;br /&gt;
&lt;br /&gt;
        maildir = mailbox.Maildir(path, MaildirMessage)&lt;br /&gt;
&lt;br /&gt;
        fakeMsg = &amp;quot;&amp;quot;&lt;br /&gt;
        if self.isTrialRun: &lt;br /&gt;
            fakeMsg = &amp;quot;(Not really) &amp;quot;&lt;br /&gt;
&lt;br /&gt;
        # Move old messages&lt;br /&gt;
        for i, msg in enumerate(maildir):&lt;br /&gt;
            if self.keepFlaggedThreads == True \&lt;br /&gt;
                    and msg.getSubjectHash() in self.keepSubjects:&lt;br /&gt;
                self.log(logging.DEBUG, &amp;quot;Keeping #%d (topic flagged)&amp;quot; % i, msg)&lt;br /&gt;
            else:&lt;br /&gt;
                if (msg.getAge() &amp;gt;= minAge) and ((not self.keepRead) or (self.keepRead and msg.isNew())):&lt;br /&gt;
                    if mode == 'trash':&lt;br /&gt;
                        self.log(logging.INFO, &amp;quot;%sTrashing #%d (old)&amp;quot; %&lt;br /&gt;
                                 (fakeMsg, i), msg)&lt;br /&gt;
                        if not self.isTrialRun:&lt;br /&gt;
                            self.trashWriter.deliver(msg)&lt;br /&gt;
                            os.unlink(msg.getFilePath())&lt;br /&gt;
                    elif mode == 'delete':&lt;br /&gt;
                        self.log(logging.INFO, &amp;quot;%sDeleting #%d (old)&amp;quot; % &lt;br /&gt;
                                 (fakeMsg, i), msg)&lt;br /&gt;
                        if not self.isTrialRun:&lt;br /&gt;
                            os.unlink(msg.getFilePath())&lt;br /&gt;
                    else: # mode == 'archive'&lt;br /&gt;
                        # Determine subfolder path&lt;br /&gt;
                        mdate = time.gmtime(msg.getDateSentOrRecd())&lt;br /&gt;
                        datePart = str(mdate[0])&lt;br /&gt;
                        if self.archiveHierDepth &amp;gt; 1:&lt;br /&gt;
                            datePart += self.folderSeperator \&lt;br /&gt;
                                        + time.strftime(&amp;quot;%m-%b&amp;quot;, mdate)&lt;br /&gt;
                        if self.archiveHierDepth &amp;gt; 2:&lt;br /&gt;
                            datePart += self.folderSeperator \&lt;br /&gt;
                                        + time.strftime(&amp;quot;%d-%a&amp;quot;, mdate)&lt;br /&gt;
                        subFolder = archiveFolder + self.folderSeperator \&lt;br /&gt;
                                    + datePart&lt;br /&gt;
                        sfPath = os.path.join(self.folderBase, &lt;br /&gt;
                                              self.folderPrefix + subFolder)&lt;br /&gt;
                        self.log(logging.INFO, &amp;quot;%sArchiving #%d to %s&amp;quot; %&lt;br /&gt;
                                 (fakeMsg, i, subFolder), msg)&lt;br /&gt;
                        if not self.isTrialRun:&lt;br /&gt;
                            # Create the subfolder if needed&lt;br /&gt;
                            if not os.path.exists(sfPath):&lt;br /&gt;
                                mkMaildir(sfPath)&lt;br /&gt;
                            # Deliver&lt;br /&gt;
                            self.__mdWriter.deliver(msg, sfPath)&lt;br /&gt;
                            os.unlink(msg.getFilePath())&lt;br /&gt;
                    self.stats[mode] += 1&lt;br /&gt;
                else:&lt;br /&gt;
                    self.log(logging.DEBUG, &amp;quot;Keeping #%d (fresh)&amp;quot; % i, msg)&lt;br /&gt;
            self.stats['total'] += 1&lt;br /&gt;
&lt;br /&gt;
    def log(self, lvl, text, msgObj):&lt;br /&gt;
        &amp;quot;&amp;quot;&amp;quot;Log some text with the subject of a message&amp;quot;&amp;quot;&amp;quot;&lt;br /&gt;
        subj = msgObj.getSubject()&lt;br /&gt;
        if subj == None:&lt;br /&gt;
            subj = &amp;quot;(no subject)&amp;quot;&lt;br /&gt;
        self.logger.log(lvl, text + &amp;quot;: &amp;quot; + subj)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
# Defaults&lt;br /&gt;
minAge = 14&lt;br /&gt;
mode = None&lt;br /&gt;
&lt;br /&gt;
logging.basicConfig()&lt;br /&gt;
logging.getLogger().setLevel(logging.DEBUG)&lt;br /&gt;
logging.disable(logging.INFO - 1)&lt;br /&gt;
logger = logging.getLogger('cleanup-maildir')&lt;br /&gt;
cleaner = MaildirCleaner()&lt;br /&gt;
&lt;br /&gt;
# Read command-line arguments&lt;br /&gt;
try:&lt;br /&gt;
    opts, args = getopt.getopt(sys.argv[1:], &lt;br /&gt;
            &amp;quot;hqvnrm:t:a:kd:&amp;quot;,&lt;br /&gt;
            [&amp;quot;help&amp;quot;, &amp;quot;quiet&amp;quot;, &amp;quot;verbose&amp;quot;, &amp;quot;version&amp;quot;, &amp;quot;mode=&amp;quot;, &amp;quot;trash-folder=&amp;quot;,&lt;br /&gt;
             &amp;quot;age=&amp;quot;, &amp;quot;keep-flagged-threads&amp;quot;, &amp;quot;keep-read&amp;quot;, &amp;quot;folder-seperator=&amp;quot;,&lt;br /&gt;
             &amp;quot;folder-prefix=&amp;quot;, &amp;quot;maildir-root=&amp;quot;, &amp;quot;archive-folder=&amp;quot;,&lt;br /&gt;
             &amp;quot;archive-hierarchy-depth=&amp;quot;, &amp;quot;trial-run&amp;quot;])&lt;br /&gt;
except getopt.GetoptError, (msg, opt):&lt;br /&gt;
    logger.error(&amp;quot;%s\n\n%s&amp;quot; % (msg, __doc__))&lt;br /&gt;
    sys.exit(2)&lt;br /&gt;
output = None&lt;br /&gt;
for o, a in opts:&lt;br /&gt;
    if o in (&amp;quot;-h&amp;quot;, &amp;quot;--help&amp;quot;):&lt;br /&gt;
        print __doc__&lt;br /&gt;
        sys.exit()&lt;br /&gt;
    if o in (&amp;quot;-q&amp;quot;, &amp;quot;--quiet&amp;quot;): &lt;br /&gt;
        logging.disable(logging.WARNING - 1)&lt;br /&gt;
    if o in (&amp;quot;-v&amp;quot;, &amp;quot;--verbose&amp;quot;): &lt;br /&gt;
        logging.disable(logging.DEBUG - 1)&lt;br /&gt;
    if o == &amp;quot;--version&amp;quot;:&lt;br /&gt;
        print __version__&lt;br /&gt;
        sys.exit()&lt;br /&gt;
    if o in (&amp;quot;-n&amp;quot;, &amp;quot;--trial-run&amp;quot;):&lt;br /&gt;
        cleaner.isTrialRun = True&lt;br /&gt;
    if o in (&amp;quot;-m&amp;quot;, &amp;quot;--mode&amp;quot;): &lt;br /&gt;
        logger.warning(&amp;quot;the --mode flag is deprecated (see --help)&amp;quot;)&lt;br /&gt;
        if a in ('trash', 'archive', 'delete'):&lt;br /&gt;
            mode = a&lt;br /&gt;
        else:&lt;br /&gt;
            logger.error(&amp;quot;%s is not a valid command&amp;quot; % a)&lt;br /&gt;
            sys.exit(2)&lt;br /&gt;
    if o in (&amp;quot;-t&amp;quot;, &amp;quot;--trash-folder&amp;quot;): &lt;br /&gt;
        cleaner.trashFolder = a&lt;br /&gt;
    if o == &amp;quot;--archive-folder&amp;quot;:&lt;br /&gt;
        cleaner.archiveFolder = a&lt;br /&gt;
    if o in (&amp;quot;-a&amp;quot;, &amp;quot;--age&amp;quot;): &lt;br /&gt;
        minAge = int(a)&lt;br /&gt;
    if o in (&amp;quot;-k&amp;quot;, &amp;quot;--keep-flagged-threads&amp;quot;): &lt;br /&gt;
        cleaner.keepFlaggedThreads = True&lt;br /&gt;
    if o in (&amp;quot;-r&amp;quot;, &amp;quot;--keep-read&amp;quot;):&lt;br /&gt;
        cleaner.keepRead = True&lt;br /&gt;
    if o == &amp;quot;--folder-seperator&amp;quot;:&lt;br /&gt;
        cleaner.folderSeperator = a&lt;br /&gt;
    if o == &amp;quot;--folder-prefix&amp;quot;:&lt;br /&gt;
        cleaner.folderPrefix = a&lt;br /&gt;
    if o == &amp;quot;--maildir-root&amp;quot;:&lt;br /&gt;
        cleaner.folderBase = a&lt;br /&gt;
    if o in (&amp;quot;-d&amp;quot;, &amp;quot;--archive-hierarchy-depth&amp;quot;): &lt;br /&gt;
        archiveHierDepth = int(a)&lt;br /&gt;
        if archiveHierDepth &amp;lt; 1 or archiveHierDepth &amp;gt; 3:&lt;br /&gt;
            sys.stderr.write(&amp;quot;Error: archive hierarchy depth must be 1, &amp;quot; +&lt;br /&gt;
                             &amp;quot;2, or 3.\n&amp;quot;)&lt;br /&gt;
            sys.exit(2)&lt;br /&gt;
        cleaner.archiveHierDepth = archiveHierDepth&lt;br /&gt;
&lt;br /&gt;
if not cleaner.folderBase:&lt;br /&gt;
    cleaner.folderBase = os.path.join(os.environ[&amp;quot;HOME&amp;quot;], &amp;quot;Maildir&amp;quot;)&lt;br /&gt;
if mode == None:&lt;br /&gt;
    if len(args) &amp;lt; 1:&lt;br /&gt;
        logger.error(&amp;quot;No command specified&amp;quot;)&lt;br /&gt;
        sys.stderr.write(__doc__)&lt;br /&gt;
        sys.exit(2)&lt;br /&gt;
    mode = args.pop(0)&lt;br /&gt;
    if not mode in ('trash', 'archive', 'delete'):&lt;br /&gt;
        logger.error(&amp;quot;%s is not a valid command&amp;quot; % mode)&lt;br /&gt;
        sys.exit(2)&lt;br /&gt;
&lt;br /&gt;
if len(args) == 0:&lt;br /&gt;
    logger.error(&amp;quot;No folder(s) specified&amp;quot;)&lt;br /&gt;
    sys.stderr.write(__doc__)&lt;br /&gt;
    sys.exit(2)&lt;br /&gt;
&lt;br /&gt;
logger.debug(&amp;quot;Mode is &amp;quot; + mode)&lt;br /&gt;
&lt;br /&gt;
# Clean each folder&lt;br /&gt;
for dir in args:&lt;br /&gt;
    logger.debug(&amp;quot;Cleaning up %s...&amp;quot; % dir)&lt;br /&gt;
    cleaner.clean(mode, dir, minAge)&lt;br /&gt;
&lt;br /&gt;
logger.info('Total messages:     %5d' % cleaner.stats['total'])&lt;br /&gt;
logger.info('Affected messages:  %5d' % cleaner.stats[mode])&lt;br /&gt;
logger.info('Untouched messages: %5d' %&lt;br /&gt;
            (cleaner.stats['total'] - cleaner.stats[mode]))&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;/div&gt;</summary>
		<author><name>Mazzotti</name></author>
		
	</entry>
</feed>