MBD : |
איזו תגובה מהירה
בתקופה האחרונה אני עובד יותר ויותר עם מייל מקומי, ואני מחפש את התוכנה הטובה ביותר. מכיוון שלא מצאתי אחת שעונה על צרכי, חשבתי לכתוב אחת בעצמי, אבל בסוף החלטתי ללכת על זו עם הפוטנציאל הגדול ביותר, ולראות איך אפשר לשפר אותה. הבחירה נפלה על הציפור, היות שיש לה תשתית לא רעה, ורק ממשק דפוק (ז"א לא כ"כ, פשוט מיושן ולא אינטיליגנטי כמעט בשום צורה). אני מתחיל לבצע שינויי ממשק די משמעותיים, חלקם בהשפעת gmail. חשבתי שאם יש עוד אנשים שזה מעניין אותם, יהיה טוב לשלב כוחות. |
תומר : |
לא זוכר איפה ראיתי את זה, אבל יש עבודה על תמיכה בתיקיות דואר מקומיות לגרסה הבאה של התוכנה. גם גישה ל־Microsoft Exchange אם מישהו צריך... |
MBD : |
זה אמור להיות קשור למה שאני מחפש? |
MBD : |
הדבר המשמעותי השלישי, זה חלון הכתיבה, שתמיד מעצבן אותי בגודל ה"מסגרת" העצומה שלו. מכיוון שרוב המיילים (שלי לפחות) יוצאים לאדם אחד, הייתי רוצה שורה אחת לנמען, שתגדל במקרה הצורך. |
תומר : |
אני מניח שאנשים רבים שותפים לדעתך זו, וככל הנראה גם יש הרחבות מתאימות. האם עשית סקר שוק ברשת?
|
MBD : |
הממשק של הציפור מאוד מאוד מסורבל. הוא אמנם "סטנדרטי" בתוכנות דואל, אבל זה לא אומר שאין לאן להתקדם.
המקום הראשון שזה בא לידי ביטוי, זו רשימת המיילים: המיילים מסודרים ברשימה, עם עמודות לבחירת המשתמש. אבל, זה מחייב רוחב בהתאם לתוכן המקסימלי, ובזבוז רב של מקום. דוגמה יפה יש בג'ימייל, שם בשורת ההודעה כלול כל המידע, בצורה רציפה, ואפילו תחילת התוכן - מה שבאמת חוסך הרבה פעמים כניסה למייל. הדבר הבא, זו חלונית ההודעה - אני גם מעדיף את השיטה של ג'ימייל, שמאפשרת לי לעבור בין תצוגת מכתב לתצוגת רשימה, ולא את שניהם במקביל. הדבר המשמעותי השלישי, זה חלון הכתיבה, שתמיד מעצבן אותי בגודל ה"מסגרת" העצומה שלו. מכיוון שרוב המיילים (שלי לפחות) יוצאים לאדם אחד, הייתי רוצה שורה אחת לנמען, שתגדל במקרה הצורך. אפשרות נוספת שאני רוצה להכניס, זה חלונית quick mail שיאפשר לי לשלוח הודעה קצרה בצורה המהירה ביותר. אני עדיין לא יודע איך בדיוק לממש את זה, אבל זה הרעיון. מה דעתך ? שים לב - מה שחסר לי זה לא יכולות מערכת, אלא נטו ממשק ידידותי וחכם יותר. |
קוד: |
try: import readline except ImportError: print "Module readline not available." else: import rlcompleter readline.parse_and_bind("tab: complete") |
קוד: |
# vim: et sw=4 ts=4 tw=79: ''' Description: Send an email. Author: sfw geek Last Udpated: 2009-06-07. ''' # Hungarian Variable Notation. # a* - Array. # c* - Constants. # d* - Dictionary. # fo* - File Object. # i* - Integer. # l* - List. # st* - Set. # s* - String. # t* - Tuple. # MODULES. import os import sys import smtplib from datetime import datetime from email.iterators import * from optparse import OptionParser from email.mime.text import MIMEText from email.mime.base import MIMEBase from email.generator import Generator from email.mime.multipart import MIMEMultipart from email.utils import COMMASPACE, CRLF, formatdate from email import encoders # CONSTANTS. cERR_MSG_PREFIX = '*ERROR*: ' # DEFINITIONS. def usage(): '''Return a string detailing how this program is used.''' sProgramName = sys.argv[0] sUsage = ''' NAME: %s SYNOPSIS: %s [OPTIONS] DESCRIPTION: Sends an email. If the value to an argument is a file path and the file exists, the file will be read line by line and the values in the file will be used. When supplying multiple email addresses as an argument, a comma should be used to separate them. Arguments with spaces should be encolsed in double quotes (").''' % (sProgramName, sProgramName) return sUsage def getArgs(): '''Get program arguments. Returns a tuple of arguement details. The 1st value is a dict of options. The 2nd value is a list of positional arguments.''' getOptParser = OptionParser(usage()) getOptParser.add_option('-b', '--body', action='store', type='string', dest='body', help='Body of email. All lines from file used if file path provided.') getOptParser.add_option('-c', '--cc', action='store', type='string', dest='cc', help='Who the email is also to be sent to (CC). One email address per line if file path provided.') getOptParser.add_option('-d', '--debug', action='store_true', dest='debug', help='Increase verbosity to help debugging.') getOptParser.add_option('-f', '--from', action='store', type='string', dest='frm', help='Who the email is from. Only first line of file used if file path provided.') getOptParser.add_option('-m', '--machine', action='store', type='string', dest='smtphost', help='The name of SMTP host used to send the email. Only first line of file used if file path provided.') getOptParser.add_option('-s', '--subject', action='store', type='string', dest='subject', help='The subject of the email. Only first line of file used if file path provided.') getOptParser.add_option('-t', '--to', action='store', type='string', dest='to', help='Who the email is to be sent to. One email address per line if file path provided.') getOptParser.add_option('-r', '--binFile', action='store', type='string', dest='binfile', help='Add binary file to body tag.') (dOpts, lPosArgs) = getOptParser.parse_args() if not (dOpts.smtphost and dOpts.to and dOpts.frm and dOpts.subject and dOpts.body and len(lPosArgs) == 0): getOptParser.print_help() sys.exit(2) return dOpts, lPosArgs def checkPythonVersion(tMinVersion): '''Throw an exception if python interperter is less than the supplied version tuple. e.g. (2, 6, 0, 'final', 0)''' iMinVerLen = len(tMinVersion) tPyVersion = sys.version_info # e.g. (2, 6, 0, 'final', 0) # Python interperter is less than supplied version error message. sErrMsg = '%sPython Version %s ' % (cERR_MSG_PREFIX, '.'.join(map(str, tMinVersion))) sErrMsg += "Or Higher Is Required To Run '%s'!" % (sys.argv[0]) if iMinVerLen > 0 and tPyVersion[0] < tMinVersion[0]: raise RuntimeError, sErrMsg if iMinVerLen > 1 and tPyVersion[1] < tMinVersion[1]: raise RuntimeError, sErrMsg if iMinVerLen > 2 and tPyVersion[2] < tMinVersion[2]: raise RuntimeError, sErrMsg if iMinVerLen > 3 and tPyVersion[3] != tMinVersion[3]: raise RuntimeError, sErrMsg if iMinVerLen > 4 and tPyVersion[3] < tMinVersion[4]: raise RuntimeError, sErrMsg def checkInput(sInput): '''Check if input is a path to a file. If it is read the file and return the contents. The input is returned if it is not a file path that exists.''' lData = [] if os.path.exists(sInput): foIn = open(sInput, 'r') for sLine in foIn: lData.append(sLine.strip()) foIn.close() else: lData.append(sInput) return lData def main(): '''Program entry point.''' # Store when program started. dtStart = datetime.now() tArgs = getArgs() # Arguments. dOpts = tArgs[0] lArgs = tArgs[1] msg = MIMEMultipart() lFrom = checkInput(dOpts.frm) msg['From'] = lFrom[0] lTo = checkInput(dOpts.to) msg['To'] = COMMASPACE.join(lTo) if dOpts.cc: # Optional. lCc = checkInput(dOpts.cc) msg['Cc'] = COMMASPACE.join(lCc) #msg['Bcc'] = COMMASPACE.join(lBcc) msg['Date'] = formatdate(localtime=True) lSubject = checkInput(dOpts.subject) msg['Subject'] = lSubject[0] lBody = checkInput(dOpts.body) msg.attach(MIMEText(CRLF.join(lBody))) ############################### ADD BIN FILE ####################################################### if dOpts.binfile: ctype = 'application/octet-stream' maintype, subtype = ctype.split('/', 1) if os.path.exists(dOpts.binfile): fp = open(dOpts.binfile, 'rb') myfile = MIMEBase(maintype, subtype) myfile.set_payload(fp.read()) fp.close() encoders.encode_base64(myfile) myfile.add_header('Content-Disposition', 'attachment', filename=dOpts.binfile) msg.attach(myfile) ########################################################################################################## lSmtpHost = checkInput(dOpts.smtphost) smtpSvr = smtplib.SMTP(lSmtpHost[0]) if dOpts.debug: # Increase display verbosity. smtpSvr.set_debuglevel(1) smtpSvr.sendmail(lFrom[0], lTo, msg.as_string()) smtpSvr.quit() if __name__ == '__main__': checkPythonVersion((2, 5)) main() |
MBD : |
לא הבנתי אותך: אתה מנסה לשכנע אותי לכתוב תוכנה חדשה בעצמי ? |