Created
November 13, 2018 22:07
-
-
Save fristonio/c671ed94152ca296f7bcd57c2ddd5e91 to your computer and use it in GitHub Desktop.
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 | |
''' | |
Obtain the APP_ID, APP_KEY from https://developer.oxforddictionaries.com | |
''' | |
import os | |
import requests | |
import sys | |
import logging | |
HELP_ARG = '--help' | |
REQUEST_TIMEOUT = 3 | |
CACHE_FILE = '.dxdata' | |
ALLOWED_CHAR_MAP = 'abcdefghijklmnopqrestuvwxyz\'' | |
API_BASE_URL = 'https://od-api.oxforddictionaries.com:443/api/v1/entries/en/{}' | |
API_HEADER = { | |
'app_id': '', | |
'app_key': '' | |
} | |
def usage(): | |
print('dx - A simple command line dictionary tool\n') | |
print('dx [WORD]...') | |
print('word - Words to find the meaning for.') | |
def is_valid_word(word): | |
for char in word.lower(): | |
if char not in ALLOWED_CHAR_MAP: | |
return False | |
return True | |
def load_cache(cache_file_path): | |
cache = {} | |
with open(cache_file_path, "r") as cache_file: | |
for line in cache_file.read().split('\n'): | |
split_list = line.split(',') | |
if len(split_list) > 1: | |
cache[split_list[0]] = ','.join(split_list[1:]) | |
return cache | |
def write_to_cache(word, meaning, cache_file): | |
line = '{}, {}\n'.format(word, meaning) | |
cache_file.write(line) | |
def search_word_and_populate(word, cache_file): | |
meaning = { | |
'status': 0, | |
'text': '' | |
} | |
try: | |
if not API_HEADER['app_id'] or not API_HEADER['app_key']: | |
meaning['status'] = 1 | |
meaning['text'] = 'Need APP_ID and APP_KEY to serach' | |
return meaning | |
req_url = API_BASE_URL.format(word) | |
res = requests.get(req_url, headers=API_HEADER, timeout=REQUEST_TIMEOUT) | |
if res.status_code != 200: | |
meaning['status'] = 4 | |
else: | |
try: | |
res = res.json() | |
meaning['text'] = res['results'][0]['lexicalEntries'][0]['entries'][0]['senses'][0]['definitions'][0] | |
if cache_file: | |
write_to_cache(word, meaning['text'], cache_file) | |
except Exception: | |
logging.error('[-] Error while parsing') | |
meaning['status'] = 5 | |
except ConnectionError: | |
logging.error('[-] Connection Error') | |
meaning['status'] = 2 | |
except requests.exceptions.RequestException: | |
logging.error('[-] Requests exception raised') | |
meaning['status'] = 3 | |
return meaning | |
def show_meaning(words): | |
HOME = os.environ['HOME'] | |
cache = {} | |
cache_file = None | |
if not HOME: | |
logging.debug('[-] No $HOME environment variable found, working without cache') | |
else: | |
cache_file_path = os.path.join(HOME, CACHE_FILE) | |
try: | |
cache_file = open(cache_file_path, "a+") | |
cache = load_cache(cache_file_path) | |
except IOError as e: | |
logging.error('[-] IO Error while opening cache') | |
cache_file = None | |
for word in words: | |
try: | |
fmt_word = word.lower() | |
if not is_valid_word(fmt_word): | |
print('[*] Not a valid word {} skipping'.format(word)) | |
continue | |
meaning = cache[fmt_word] | |
print("[*] {} : {}".format(word, meaning)) | |
except KeyError: | |
meaning = search_word_and_populate(word, cache_file) | |
if meaning['status'] == 0: | |
cache[fmt_word] = meaning['text'] | |
print('[*] {} : {}'.format(word, meaning['text'])) | |
else: | |
print('[-] Error while searching for meaning of {}'.format(word)) | |
cache_file.close() | |
if __name__ == '__main__': | |
args = sys.argv[1:] | |
if len(args) == 0 or HELP_ARG in args: | |
usage() | |
sys.exit(0) | |
show_meaning(args) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment