[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