[Tutor] Style/Conceptual Help

ebgreen@customdatasoft.com ebgreen at customdatasoft.com
Wed Nov 2 15:52:49 CET 2005


I had posted once before with a TKinter problem that I was having and it was
solved in one message so thanks a lot to the List. I now have working code and
I would be interested in some input/suggestions on the pythonicness of the way
I did things and on style, or anything else you see that I can improve. I have
some things that I am already planning as improvements:
-Menus - Right now there are none. I need to put some in with all of the options
that I want.
-Options - Right now there are 4 options that are available (sourcedir,
targetdir, deleteold, and extensions) and they are stored in an INI file. I
would like to make the options configurable from within the app and potentially
use a DB for storage.
-Logging - There is none right now and I am a fan of having logs to look back at
when there is a problem to diagnose.


Here is the code I have so far. Any input would be great.

from Tkinter import *
import PIL.Image as image
import PIL.ImageTk as imagetk
import ConfigParser
import os
import time
import shutil
from sys import exit


def GetEndString(number):
   '''GetEndString(number)
           Takes an integer or an integer like string and returns the proper
English
           ordinal ending string for the number.
   Examples:
       >>> print GetEndString(1)
       st
       >>> print GetEndString(2)
       nd
       >>> print GetEndString(3)
       rd
       >>> print GetEndString(4)
       th
       >>> print GetEndString(11)
       th
       >>> print GetEndString(12)
       th
       >>> print GetEndString(13)
       th
       >>> print GetEndString(130112)
       th
       '''
   number = str(number)
   #The ending is different for 11 and 12 teens
   if number[len(number)-2:] == '11' or number[len(number)-2:] == '12' or
number[len(number)-2:] == '13':
       return "th"
   #otherwise, the ending is a function of the last digit
   enddict = {'1':'st',
          '2':'nd',
          '3':'rd',
          '4':'th',
          '5':'th',
          '6':'th',
          '7':'th',
          '8':'th',
          '9':'th',
          '0':'th'}
   lastdigit = number[-1:]
   return enddict[lastdigit]



class MyApp:
   def __init__(self, parent):
       self.myParent = parent
       self.myContainer1 = Frame(parent)
       self.myContainer1.configure()
       self.myContainer1.pack()

       self.button1 = Button(self.myContainer1)
       self.button1.configure(text="Copy Pics", font=("Arial Black", "24"))
       self.button1.pack()
       self.button1.bind("<Button-1>", self.button1Click)
       self.button1.bind("<Motion>", self.button1Motion)
       self.button1.bind("<Leave>", self.button1Leave)

       self.tvStat = StringVar()
       self.tvStat.set("")

       self.tvFrom = StringVar()
       self.tvFrom.set("")

       self.tvTo = StringVar()
       self.tvTo.set("")

       self.tvMid = StringVar()
       self.tvMid.set("")

       self.lblStat = Label(self.myContainer1)
       self.lblStat.configure(textvariable = self.tvStat)
       self.lblStat.pack()

       self.lblFrom = Label(self.myContainer1)
       self.lblFrom.configure(textvariable = self.tvFrom)
       self.lblFrom.pack()

       self.lblMid = Label(self.myContainer1)
       self.lblMid.configure(textvariable = self.tvMid)
       self.lblMid.pack()

       self.lblTo = Label(self.myContainer1)
       self.lblTo.configure(textvariable = self.tvTo)
       self.lblTo.pack()

       self.canvas1 = Canvas(self.myContainer1)
       self.canvas1.configure(width=700, height=300)
       self.canvas1.pack()

   def button1Motion(self, event):
       self.button1.configure(bg="blue", fg="yellow")

   def button1Leave(self, event):
       self.button1.configure(bg="#fff", fg="black")

   def button1Click(self, event):
       files = {}
       nameList = []
       #Import config information from the ini file
       configfile = "./GetPics.ini"
       config = ConfigParser.ConfigParser()
       try:
           config.read(configfile)
           sourcedirloc = config.get("GetPics", "sourcedir")
           targetdirloc = config.get("GetPics", "targetdir")
           deleteold = config.get("GetPics", "deleteold")
           extList = config.get("GetPics", "extensions").lower().split(",")
       except ConfigParser.NoSectionError, detail:
           self.tvStat.set("There was an error while reading the ini file: " +
str(detail) + os.linesep +
                           "Please correct the problem then try again")
           return()
       #OPen the source dir and get a list of the files making the new name and
path as you go
       sourcefiles = os.listdir(sourcedirloc)
       files = {}
       for file in sourcefiles:
           if os.path.splitext(file)[1].lower()[1:] not in extList: continue
           filepath = sourcedirloc + "/" + file
           if files.has_key(filepath):
               #The file is duplicated?
               pass
           else:
               files[filepath] = {}
               files[filepath]['originalname'] = file
               files[filepath]['modtuple'] =
time.localtime(os.stat(filepath).st_mtime)
               files[filepath]['size'] = os.stat(filepath).st_size
               files[filepath]['monthdir'] = targetdirloc + "/" + \
                                             time.strftime('%Y-%m',
time.localtime(os.stat(filepath).st_mtime))
               files[filepath]['daydir'] = files[filepath]['monthdir'] + "/" +
\
                                           time.strftime('%d',
time.localtime(os.stat(filepath).st_mtime)) + \
                                           GetEndString(time.strftime('%d',
time.localtime(os.stat(filepath).st_mtime)))
               files[filepath]['newname'] = files[filepath]['daydir'] + "/" +
time.strftime('%Y-%m-%d-%H-%M-%S', time.localtime(os.stat(filepath).st_mtime))
+ os.path.splitext(file)[1]
               #Now check to see if a file with this name already exists and
increment the name if it does
               n = 1
               testName = files[filepath]['newname']
               while os.path.isfile(testName) or testName in nameList:
                   testName = os.path.splitext(files[filepath]['newname'])[0] +
"-" + str(n) + os.path.splitext(files[filepath]['newname'])[1]
                   n += 1
               files[filepath]['newname'] = testName
               nameList.append(testName)
       #Copy all of the file to the target dir
       for file in files.keys():
           self.tvStat.set("Copying...")
           #Check for the dir and create it if needed:
           if not os.path.isdir(files[file]['monthdir']):
               self.tvFrom.set("Creating (monthdir) " +
files[file]['monthdir'])
               os.makedirs(files[file]['monthdir'])
           if not os.path.isdir(files[file]['daydir']):
               self.tvFrom.set("Creating (daydir) " + files[file]['daydir'])
               os.makedirs(files[file]['daydir'])
           #copy the file
           self.tvFrom.set(file)
           self.tvMid.set("TO")
           self.tvTo.set(files[file]['newname'])
           try:
               self.DisplayImage(file)
           except:
               print "ERROR:", sys.exc_info()[0]
           shutil.copy2(file, files[file]['newname'])

       #Go back and remove the sorce files checking that the target file exists
first
       self.tvStat.set("Finished with copies...")
       self.tvFrom.set("")
       self.tvMid.set("")
       self.tvTo.set("")
       for file in files.keys():
           if os.stat(files[file]['newname']).st_size == files[file]['size']
and deleteold.lower() == "true":
               self.tvStat.set("Deleting file...")
               self.tvFrom.set(file)
               os.remove(file)
           else:
               self.tvStat.set("There was an error with " + file)
       self.tvStat.set("Copy done.")
       self.tvFrom.set(str(len(files)) + " files were copied.")
       self.tvMid.set("")
       self.tvTo.set("")

   def DisplayImage(self, file):
       im = image.open(file)
       origx, origy = im.size
       if origx > origy:
           ratio = 250./origx
       else:
           ratio = 250./origy
       size = (int(ratio*origx), int(ratio*origy))
       out = im.resize(size)
       pic1 = imagetk.PhotoImage(out)
       self.canvas1.create_image(350, 150, image = pic1, anchor=CENTER)
       self.myParent.update_idletasks()
       self.canvas1.pack()


# run it ...
root = Tk()

myapp = MyApp(root)
root.mainloop()




More information about the Tutor mailing list