Last active
August 29, 2015 14:11
-
-
Save alexwlchan/b4554a6703e1be914a6b to your computer and use it in GitHub Desktop.
A command-line tool for managing acronyms
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/python | |
"""A script for managing a dictionary of acronyms. For context, see the | |
associated blog post: http://alexwlchan.net/2014/12/acronyms/ | |
Invoke with the -h or --help flag for a usage message: | |
$ ./acronyms.py -h | |
Invoke with the -a or --add flag to add an acronym: | |
$ ./acronyms.py -a NASA | |
$ ./acronyms.py --add IETF | |
You will then be prompted to fill in some details. | |
Invoke with the -l or --lookup flag to look up an existing acronym: | |
$ ./acronyms.py -l CLI | |
$ ./acronyms.py --lookup GUI | |
""" | |
import argparse | |
import json | |
import os | |
import re | |
import sys | |
import textwrap | |
ACRONYMS_FILE = 'acronyms.json' | |
#----------------------------------------------------------------------------- | |
# Set up the options for argparse | |
#----------------------------------------------------------------------------- | |
parser = argparse.ArgumentParser(description="A script for looking up acronyms.") | |
parser.add_argument('-a', '--add', dest='new_acronym', | |
help="add a new acronym") | |
parser.add_argument('-l', '--lookup', metavar='ACRONYM', | |
help="look up an existing acronym") | |
args = parser.parse_args() | |
#----------------------------------------------------------------------------- | |
# Utility functions | |
#----------------------------------------------------------------------------- | |
def read_acronyms_file(acronym_file=ACRONYMS_FILE): | |
"""Get a list of existing acronyms from a JSON file, or create the file if | |
it does not exist. | |
""" | |
if not os.path.isfile(acronym_file): | |
with open(acronym_file, 'w') as outfile: | |
outfile.write('[]') | |
with open(acronym_file, 'r') as json_data: | |
data = json.load(json_data) | |
return data | |
def write_acronyms_file(data, acronym_file=ACRONYMS_FILE): | |
"""Write the list of acronyms to a JSON file.""" | |
with open(acronym_file, 'w') as outfile: | |
outfile.write(json.dumps(data)) | |
def get_new_acronym(acronym=None): | |
"""Ask the user for information about the new acronym.""" | |
if acronym is None: | |
acronym = raw_input("What is the new acronym?\n") | |
else: | |
print("Creating an entry for acronym \"%s\"." % acronym) | |
expansion = raw_input("\nWhat does %s stand for?\n" % acronym) | |
description = raw_input("\nAnd what does this mean? (optional)\n") | |
new_acronym = { | |
"acronym": acronym, | |
"expansion": expansion | |
} | |
if description: | |
new_acronym["description"] = description | |
return new_acronym | |
def add_new_acronym(acronym): | |
"""Ask the user for the new acronym, and write it to file.""" | |
new_acronym = get_new_acronym(acronym) | |
data = read_acronyms_file() | |
data.append(new_acronym) | |
write_acronyms_file(data) | |
class color: | |
BOLD = '\033[1m' | |
END = '\033[0m' | |
def print_acronym(entry): | |
"""Pretty print an acronym to the console.""" | |
print(color.BOLD + entry["acronym"] + ": " + entry["expansion"] + color.END) | |
if "description" in entry: | |
wrapper = textwrap.TextWrapper(initial_indent=" " * 4, width=70, | |
subsequent_indent=" " * 4) | |
print(wrapper.fill(entry["description"])) | |
print("") | |
#----------------------------------------------------------------------------- | |
# Mainline program function | |
#----------------------------------------------------------------------------- | |
def main(): | |
# If no arguments are supplied, print the help message and exit | |
if len(sys.argv) == 1: | |
parser.print_help() | |
sys.exit(0) | |
# If the --add flag is supplied, create a new acronym and write it out to | |
# the database | |
if args.new_acronym is not None: | |
add_new_acronym(args.new_acronym) | |
# If we're looking up an existing acronym, do a search on the list of | |
# existing acronyms | |
if args.lookup is not None: | |
data = read_acronyms_file() | |
matches = [] | |
for entry in data: | |
# We include both a perfect match, and a match on just the letters | |
# so 'abc' matches 'A-BC'. It doesn't coerce Unicode chars to their | |
# ASCII counterparts, but I also don't use any acronyms that include | |
# accented characters. | |
possible_matches = [ | |
entry["acronym"].lower(), | |
re.sub('[^a-z]', '', entry["acronym"].lower()) | |
] | |
if args.lookup.lower() in possible_matches: | |
matches.append(entry) | |
for entry in sorted(matches, key=lambda entry: entry["expansion"]): | |
print_acronym(entry) | |
# If we haven't found the acronym, offer to create it | |
if not matches: | |
create = raw_input("I didn't find that acronym. " | |
"Would you like to create it? [y/N]\n") | |
if create.lower() in ['y', 'yes']: | |
add_new_acronym(args.lookup) | |
else: | |
print("Okay, never mind.") | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment