Created
October 8, 2012 21:42
-
-
Save dsc/3855195 to your computer and use it in GitHub Desktop.
Base class for Python CLI scripts, with example using PIL to display image dimensions on the shell.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
""" Prints image dimensions. | |
""" | |
__author__ = 'David Schoonover <[email protected]>' | |
import sys, re, argparse | |
from subprocess import Popen, PIPE, STDOUT, check_output | |
from path import path | |
from bunch import * | |
from lessly import * | |
from script import Script | |
from PIL import Image | |
class ImgScript(Script): | |
def __init__(self, *args, **options): | |
super(ImgScript, self).__init__(*args, **options) | |
if self.includePath is None: | |
self.includePath = self.__options__['includePath'] = len(self.images) > 1 | |
def run(self): | |
for img_path in map(path, self.images): | |
if not img_path.isfile(): continue | |
info = [] | |
if self.includePath: info += [img_path] | |
img = Image.open(img_path) | |
img.load() | |
w, h = img.size | |
if self.onlyPrint: | |
info += [w if self.onlyPrint == 'w' else h] | |
else: | |
info += [w, h] | |
print self.sep.join(map(str, info)) | |
parser = argparse.ArgumentParser(description=__doc__) | |
parser.add_argument("-p", "--path", dest='includePath', action="store_true", default=None, | |
help="Print image path along with dimensions. This defaults to True when more than one path is supplied.") | |
parser.add_argument("-P", "--no-path", dest='includePath', action="store_false", default=None, | |
help="Do not print image path along with dimensions, even when more than one path is supplied.") | |
parser.add_argument("-W", "--width", dest='onlyPrint', action='store_const', default=None, const='w', | |
help="Only print image width.") | |
parser.add_argument("-H", "--height", dest='onlyPrint', action='store_const', default=None, const='h', | |
help="Only print image height.") | |
parser.add_argument("-s", "--sep", default=' ', | |
help="Separator between dimensions (and path, if included). [default: %(default)r]") | |
parser.add_argument('images', nargs='+') | |
if __name__ == '__main__': | |
sys.exit(ImgScript.main() or 0) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# -*- coding: utf-8 -*- | |
from __future__ import print_function | |
import sys, argparse, colorama | |
from colorama import Fore, Back, Style | |
__all__ = ('Script',) | |
ERROR = '%sError:%s ' % (Fore.RED, Style.RESET_ALL) | |
def add_colors(d): | |
for color in 'BLACK BLUE CYAN GREEN MAGENTA RED WHITE YELLOW RESET'.split(): | |
d.setdefault(color, getattr(Fore, color)) | |
for style in 'BRIGHT DIM NORMAL RESET_ALL'.split(): | |
d.setdefault(style, getattr(Style, style)) | |
return d | |
class Script(object): | |
"Scripting base class." | |
verbose = True | |
parser = None | |
def __init__(self, *args, **options): | |
self.__dict__.update(**options) | |
self.__args__ = args | |
self.__options__ = options | |
def log(self, message, *args, **kwargs): | |
"Log a message to stderr if verbose." | |
_end = kwargs.pop('_end', '\n') | |
_outfile = kwargs.pop('_outfile', sys.stderr) | |
_is_error = kwargs.pop('_is_error', False) | |
if self.verbose or _is_error: | |
kwargs.setdefault('self', self) | |
msg = (ERROR if _is_error else '') + message.format(*args, **kwargs) + Style.RESET_ALL | |
print(msg, end=_end, file=_outfile) | |
return True | |
def error(self, message, *args, **kwargs): | |
"Log a non-fatal error to stderr. (For fatal errors, just raise.)" | |
kwargs.setdefault('_is_error', True) | |
return self.log(message, *args, **kwargs) | |
def run(self): | |
raise Exception('Script.run() is not implemented!') | |
def __call__(self, *args, **kwargs): | |
return self.run(*args, **kwargs) | |
def __repr__(self): | |
return '{self.__class__.__name__}(options={self.__options__!r})'.format(self=self) | |
def __str__(self): | |
return repr(self) | |
@classmethod | |
def parse(cls, *args, **overrides): | |
parsed = cls.parser.parse_args(args or None) | |
values = dict(**parsed.__dict__) | |
values.update(overrides) | |
return values | |
@classmethod | |
def create(cls, *args, **overrides): | |
values = cls.parse(*args, **overrides) | |
return cls(**values) | |
@classmethod | |
def main(cls, *args, **overrides): | |
return cls.create(*args, **overrides)() or 0 | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment