Skip to content

Instantly share code, notes, and snippets.

@fristonio
Created November 13, 2018 22:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fristonio/c671ed94152ca296f7bcd57c2ddd5e91 to your computer and use it in GitHub Desktop.
Save fristonio/c671ed94152ca296f7bcd57c2ddd5e91 to your computer and use it in GitHub Desktop.
#!/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