use with instead of try ... finally

This commit is contained in:
Mattias Andrée 2012-09-30 00:53:16 +02:00
parent 8231dbe8f6
commit 59247bf6e9

View file

@ -30,6 +30,7 @@ import random
from subprocess import Popen, PIPE
'''
The version of ponysay
'''
@ -56,7 +57,6 @@ class Ponysay():
args.help()
return
if args.opts['-h'] is not None: args.help()
elif args.opts['--quoters'] is not None: self.quoters()
elif args.opts['--onelist'] is not None: self.onelist()
@ -85,6 +85,7 @@ class Ponysay():
Use extra ponies
'''
def __extraponies(self, args = None):
## If extraponies are used, change ponydir to extraponydir
if args is None:
ponydirs[:] = extraponydirs
elif args.opts['-F'] is not None:
@ -96,6 +97,7 @@ class Ponysay():
Use best.pony if nothing else is set
'''
def __bestpony(self, args):
## Set best.pony as the pony to display if none is selected
if (args.opts['-f'] is None) or (args.opts['-q'] is None) or (len(args.opts['-q']) == 0):
for ponydir in ponydirs:
if os.path.isfile(ponydir + 'best.pony') or os.path.islink(ponydir + 'best.pony'):
@ -108,25 +110,24 @@ class Ponysay():
Apply pony name remapping to args according to UCS settings
'''
def __ucsremap(self, args):
## Read UCS configurations
env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
ucs_conf = 0
if env_ucs in ('yes', 'y', '1'): ucs_conf = 1
elif env_ucs in ('harder', 'h', '2'): ucs_conf = 2
## Stop USC is not used
if ucs_conf == 0:
return
## Read all lines in all UCS → ASCII map files
maplines = []
for ucsmap in ucsmaps:
if os.path.isfile(ucsmap):
mapfile = None
try:
mapfile = open(ucsmap, 'rb')
with open(ucsmap, 'rb') as mapfile:
maplines += [line.replace('\n', '') for line in mapfile.read().decode('utf8', 'replace').split('\n')]
finally:
if mapfile is not None:
mapfile.close()
## Create USC → ASCII mapping from read lines
map = {}
stripset = ' \t' # must be string, wtf! and way doesn't python's doc say so
for line in maplines:
@ -136,6 +137,7 @@ class Ponysay():
ascii = line[s + 1:].strip(stripset)
map[ucs] = ascii
## Apply USC → ASCII mapping to -f and -q arguments
for flag in ('-f', '-q'):
if args.opts[flag] is not None:
for i in range(0, len(args.opts[flag])):
@ -151,25 +153,24 @@ class Ponysay():
Apply USC:ise pony names according to UCS settings
'''
def __ucsise(self, ponies, links = None):
## Read UCS configurations
env_ucs = os.environ['PONYSAY_UCS_ME'] if 'PONYSAY_UCS_ME' in os.environ else ''
ucs_conf = 0
if env_ucs in ('yes', 'y', '1'): ucs_conf = 1
elif env_ucs in ('harder', 'h', '2'): ucs_conf = 2
## Stop USC is not used
if ucs_conf == 0:
return
## Read all lines in all UCS → ASCII map files
maplines = []
for ucsmap in ucsmaps:
if os.path.isfile(ucsmap):
mapfile = None
try:
mapfile = open(ucsmap, 'rb')
with open(ucsmap, 'rb') as mapfile:
maplines += [line.replace('\n', '') for line in mapfile.read().decode('utf8', 'replace').split('\n')]
finally:
if mapfile is not None:
mapfile.close()
## Create USC → ASCII mapping from read lines
map = {}
stripset = ' \t' # must be string, wtf! and way doesn't python's doc say so
for line in maplines:
@ -179,6 +180,7 @@ class Ponysay():
ascii = line[s + 1:].strip(stripset)
map[ascii] = ucs
## Apply USC → ACII mapping to ponies, by alias if weak settings
if ucs_conf == 1:
for pony in ponies:
if pony in map:
@ -197,20 +199,24 @@ class Ponysay():
def __getponypath(self, names = None):
ponies = {}
## List all pony files, without the .pony ending
for ponydir in ponydirs:
for ponyfile in os.listdir(ponydir):
pony = ponyfile[:-5]
if pony not in ponies:
ponies[pony] = ponydir + ponyfile
## Filter out all choosen ponies
if not names == None:
for name in names:
if os.path.exists(name):
ponies[name] = name
## If there is not select ponies, choose all of them
if names == None:
names = list(ponies.keys())
## Select a random pony of the choosen onles
pony = names[random.randrange(0, len(names))]
if pony not in ponies:
sys.stderr.write('I have never heard of anypony named %s\n' % (pony));
@ -223,6 +229,7 @@ class Ponysay():
Returns a set with all ponies that have quotes and are displayable
'''
def __quoters(self):
## List all unique quote files
quotes = []
quoteshash = set()
_quotes = []
@ -234,6 +241,7 @@ class Ponysay():
quoteshash.add(quote)
quotes.append(quote)
## Create a set of all ponyes that have quotes
ponies = set()
for ponydir in ponydirs:
for pony in os.listdir(ponydir):
@ -251,11 +259,13 @@ class Ponysay():
Returns a list with all (pony, quote file) pairs
'''
def __quotes(self):
## Get all ponyquote files
quotes = []
for quotedir in quotedirs:
quotes += [quotedir + item for item in os.listdir(quotedir)]
rc = []
## Create list of all ponyquote file-pairs
rc = []
for ponydir in ponydirs:
for pony in os.listdir(ponydir):
if not pony[0] == '.':
@ -273,6 +283,7 @@ class Ponysay():
Gets the size of the terminal in (rows, columns)
'''
def __gettermsize(self):
## Call `stty` to determine the size of the terminal, this way is better then using python's ncurses
termsize = Popen(['stty', 'size'], stdout=PIPE, stdin=sys.stderr).communicate()[0]
termsize = termsize.decode('utf8', 'replace')[:-1].split(' ') # [:-1] removes a \n
termsize = [int(item) for item in termsize]
@ -288,16 +299,20 @@ class Ponysay():
Columnise a list and prints it
'''
def __columnise(self, ponies):
## Get terminal width, and a 2 which is the space between columns
termwidth = self.__gettermsize()[1] + 2
## Sort the ponies, and get the cells' widths, and the largest width + 2
ponies.sort(key = lambda pony : pony[0])
widths = [UCS.dispLen(pony[0]) for pony in ponies]
width = max(widths) + 2 # longest pony file name + space between columns
cols = termwidth // width
## Calculate the number of rows and columns, can create a list of empty columns
cols = termwidth // width # do not believe electricians, this means ⌊termwidth / width⌋
rows = (len(ponies) + cols - 1) // cols
columns = []
for c in range(0, cols): columns.append([])
## Fill the columns with cells of ponies
(y, x) = (0, 0)
for j in range(0, len(ponies)):
cell = ponies[j][1] + ' ' * (width - widths[j]);
@ -307,6 +322,7 @@ class Ponysay():
x += 1
y = 0
## Make the columnisation nicer by letting the last row be partially empty rather than the last column
diff = rows * cols - len(ponies)
if diff > 2:
c = cols - 1
@ -318,6 +334,7 @@ class Ponysay():
diff -= 1
pass
## Create rows from columns
lines = []
for r in range(0, rows):
lines.append([])
@ -325,7 +342,8 @@ class Ponysay():
if r < len(columns[c]):
line = lines[r].append(columns[c][r])
print('\n'.join([''.join(line)[:-2] for line in lines]));
## Print the matrix, with one extra blank row
print('\n'.join([''.join(line)[:-2] for line in lines]))
print()
@ -333,20 +351,26 @@ class Ponysay():
Lists the available ponies
'''
def list(self):
## Get all quoters
quoters = self.__quoters()
for ponydir in ponydirs: # Loop ponydirs
## Get all ponies in the directory
_ponies = os.listdir(ponydir)
## Remove .pony from all files and skip those that does not have .pony
ponies = []
for pony in _ponies:
if (len(pony) > 5) and (pony[-5:] == '.pony'):
ponies.append(pony[:-5])
## UCS:ise pony names, they are already sorted
self.__ucsise(ponies)
## If ther directory is not empty print its name and all ponies, columnised
if len(ponies) == 0:
continue
print('\033[1mponies located in ' + ponydir + '\033[21m')
self.__columnise([(pony, '\033[1m' + pony + '\033[21m' if pony in quoters else pony) for pony in ponies])
@ -354,22 +378,30 @@ class Ponysay():
Lists the available ponies with alternatives inside brackets
'''
def linklist(self):
## Get the size of the terminal and all ponies with quotes
termsize = self.__gettermsize()
quoters = self.__quoters()
for ponydir in ponydirs: # Loop ponydirs
## Get all pony files in the directory
_ponies = os.listdir(ponydir)
## Remove .pony from all files and skip those that does not have .pony
ponies = []
for pony in _ponies:
if (len(pony) > 5) and (pony[-5:] == '.pony'):
ponies.append(pony[:-5])
## If there are no ponies in the directory skip to next directory, otherwise, print the directories name
if len(ponies) == 0:
continue
print('\033[1mponies located in ' + ponydir + '\033[21m')
## UCS:ise pony names
pseudolinkmap = {}
self.__ucsise(ponies, pseudolinkmap)
## Create targetlink-pair, with `None` as link if the file is not a symlink or in `pseudolinkmap`
pairs = []
for pony in ponies:
if pony in pseudolinkmap:
@ -377,6 +409,7 @@ class Ponysay():
else:
pairs.append((pony, os.path.realpath(ponydir + pony + '.pony') if os.path.islink(ponydir + pony + '.pony') else None))
## Create map from source pony to alias ponies for each pony
ponymap = {}
for pair in pairs:
if (pair[1] is None) or (pair[1] == ''):
@ -391,7 +424,7 @@ class Ponysay():
else:
ponymap[target] = [pair[0]]
width = 0
## Create list of source ponies concatenated with alias ponies in brackets
ponies = {}
for pony in ponymap:
w = UCS.dispLen(pony)
@ -409,22 +442,24 @@ class Ponysay():
item += '\033[1m' + sym + '\033[21m' if (sym in quoters) else sym
item += ')'
ponies[(item.replace('\033[1m', '').replace('\033[21m', ''), item)] = w
if width < w:
width = w
## Print the ponies, columnised
self.__columnise(list(ponies))
'''
Lists with all ponies that have quotes and are displayable
Lists with all ponies that have quotes and are displayable, on one column without anything bold or otherwise formated
'''
def quoters(self):
last = ''
ponies = []
for pony in self.__quoters():
ponies.append(pony)
## Get all quoters
ponies = self.__quoters()
## USC:ise and sort
self.__ucsise(ponies)
ponies.sort()
## Print each one on a seperate line, but skip duplicates
last = ''
for pony in ponies:
if not pony == last:
last = pony
@ -432,19 +467,26 @@ class Ponysay():
'''
Lists the available ponies one one column without anything bold
Lists the available ponies on one column without anything bold or otherwise formated
'''
def onelist(self):
last = ''
## Get all pony files
_ponies = []
for ponydir in ponydirs: # Loop ponydirs
_ponies += os.listdir(ponydir)
## Remove .pony from all files and skip those that does not have .pony
ponies = []
for pony in _ponies:
if (len(pony) > 5) and (pony[-5:] == '.pony'):
ponies.append(pony[:-5])
## USC:ise and sort
self.__ucsise(ponies)
ponies.sort()
## Print each one on a seperate line, but skip duplicates
last = ''
for pony in ponies:
if not pony == last:
last = pony
@ -525,13 +567,8 @@ class Ponysay():
for elem in ('\\', '/', 'ww', 'ee', 'nw', 'nnw', 'n', 'nne', 'ne', 'nee', 'e', 'see', 'se', 'sse', 's', 'ssw', 'sw', 'sww', 'w', 'nww'):
map[elem] = []
balloonstream = None
try:
balloonstream = open(balloonfile, 'rb')
with open(balloonfile, 'rb') as balloonstream:
data = [line.replace('\n', '') for line in balloonstream.read().decode('utf8', 'replace').split('\n')]
finally:
if balloonstream is not None:
balloonstream.close()
last = None
for line in data:
@ -663,13 +700,8 @@ class Ponysay():
if not len(pairs) == 0:
pair = pairs[random.randrange(0, len(pairs))]
qfile = None
try:
qfile = open(pair[1], 'rb')
with open(pair[1], 'rb') as qfile:
args.message = qfile.read().decode('utf8', 'replace').strip()
finally:
if qfile is not None:
qfile.close()
args.opts['-f'] = [pair[0]]
elif len(args.opts['-q']) == 0:
sys.stderr.write('Princess Celestia! All the ponies are mute!\n')
@ -735,14 +767,9 @@ class Ponysay():
if not os.path.isfile(cachedir + '/.version'):
newversion = True
else:
cachev = None
try:
cachev = open(cachedir + '/.version', 'rb')
with open(cachedir + '/.version', 'rb') as cachev:
if cachev.read().decode('utf8', 'replace').replace('\n', '') == KMS_VERSION:
newversion = True
finally:
if cachev is not None:
cachev.close()
if newversion:
for cached in os.listdir(cachedir):
cached = cachedir + '/' + cached
@ -750,13 +777,8 @@ class Ponysay():
shutil.rmtree(cached, False)
else:
os.remove(cached)
cachev = None
try:
cachev = open(cachedir + '/.version', 'w+')
with open(cachedir + '/.version', 'w+') as cachev:
cachev.write(KMS_VERSION)
finally:
if cachev is not None:
cachev.close()
kmsponies = cachedir + '/kmsponies/' + palettefile
kmspony = (kmsponies + pony).replace('//', '/')
@ -1157,13 +1179,8 @@ class Backend():
Loads the pony file
'''
def __loadFile(self):
ponystream = None
try:
ponystream = open(self.ponyfile, 'rb')
with open(self.ponyfile, 'rb') as ponystream:
self.pony = ponystream.read().decode('utf8', 'replace')
finally:
if ponystream is not None:
ponystream.close()
'''