Skip to content

Commit

Permalink
first major modification
Browse files Browse the repository at this point in the history
  • Loading branch information
gavinzbq committed Jun 22, 2017
1 parent 9a823d9 commit 14f31a2
Show file tree
Hide file tree
Showing 8 changed files with 263 additions and 87 deletions.
Binary file added .tox.ini.swp
Binary file not shown.
43 changes: 17 additions & 26 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,29 +1,20 @@
# Config file for automatic testing at travis-ci.org
# This file will be regenerated if you run travis_pypi_setup.py

language: python
python:
- 3.5
- 3.4
- 3.3
- 2.7
- 2.6

# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors
install: pip install -U tox-travis

# command to run tests, e.g. python setup.py test
script: tox

# After you create the Github repo and add it to Travis, run the
# travis_pypi_setup.py script to finish PyPI deployment setup
# This file was autogenerated and will overwrite each time you run travis_pypi_setup.py
deploy:
provider: pypi
true:
python: 2.7
repo: gavinzbq/synonym
tags: true
distributions: sdist bdist_wheel
user: gavinzbq
password:
secure: PLEASE_REPLACE_ME
on:
tags: true
repo: gavinzbq/synonym
python: 2.7
secure: cK1HjxAb3d8mxQEuJBZ16puwieKBFlurC43L+3/9pXGoM9RHxW1konEhroxKHaxa3K4ul3lvOr0o9X/1/nlznkCo9tlh3z2lnusvK0Adj1Wzg+DfkfWzm7fBnlPuTY5o1ypMbImWSOfpP9Ia1ALM1IphMjaIlSQGXMTN/p+tn8QEclQaEH/j0LfNTwiyhH+bP41DFXljaQO1lRHdwzkuUlVjBRQ7lL4tA0U0fDEqPQVOhfGY2hABP+dzq37YRXVTlUyV1ntYQtIB0HrFTeOwRQDaZCc3UqbEx6vscBP2s5XzgbyO+yn7ViO+u5az0BRfZjTtQ/qD1ziJww5Wvh3L630ya5YrYcIrdaBQ1aur+dBfAAGHYAvHEvK3zpdU7nV+9TQReJmEyfvGlTmDSEESmst/v5oHAlGKdRE15GtsfQe4JygpsgQIqN/JG+f+Bsa6n2m7zefzyXmZQLEbTu4uhoAsc/Ba2g0fznB+X516ta1gj78Rutb+adWf75rSvIaqgCTbH29vOWlcx1mKZfVk3Of99qIQBzclOTgsIuy9q9bEnErkI7oqt0H0flj+NuQf17G1z4aZ9VuuEzA8geRkblqHgWS7qnTRs5MeBaS28w3T1qdUlbd/KLiZq0OcV/qyO6gm0b7sQhUOwSeDUqeh3RuQlb8MCg5oazJ6DzHAoQw=
provider: pypi
user: gavinzbq
install: pip install -U tox-travis
language: python
python:
- 3.5
- 3.4
- 3.3
- 2.7
- 2.6
script: tox
4 changes: 3 additions & 1 deletion requirements_dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,6 @@ coverage==4.1
Sphinx==1.4.8
cryptography==1.7
PyYAML==3.11

pyquery==1.2.17
requests==2.18.1
crayons==0.1.2
15 changes: 10 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"""The setup script."""

from setuptools import setup, find_packages
import synonym

with open('README.rst') as readme_file:
readme = readme_file.read()
Expand All @@ -12,7 +13,9 @@
history = history_file.read()

requirements = [
'Click>=6.0',
'pyquery',
'requests',
'crayons'
# TODO: put package requirements here
]

Expand All @@ -26,16 +29,18 @@

setup(
name='synonym',
version='0.1.0',
description="synonym: instant synonym answers via command line.",
version=synonym.__version__,
description="synonym: Instant synonym answers via command line.",
long_description=readme + '\n\n' + history,
author="Shanyun Gao",
author_email='shanyun@g.clemson.edu',
maintainer="Shanyun Gao",
maintainer_email='shanyun@g.clemson.edu',
url='https://github.com/gavinzbq/synonym',
packages=find_packages(include=['synonym']),
entry_points={
'console_scripts': [
'synonym=synonym.cli:main'
'synonym = synonym.synonym:command_line_runner',
]
},
include_package_data=True,
Expand All @@ -55,8 +60,8 @@
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
],
test_suite='tests',
tests_require=test_requirements,
setup_requires=setup_requirements,
)
17 changes: 0 additions & 17 deletions synonym/cli.py

This file was deleted.

234 changes: 233 additions & 1 deletion synonym/synonym.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,235 @@
# -*- coding: utf-8 -*-
#!/usr/bin/env python

"""Main module."""
########################################################
#
# synonym - instant synonym answers via command line
# written by Shanyun Gao (shanyungau@gmail.com)
# inspired by howdoi (http://github.com/gleitz/howdoi )
#
########################################################


import argparse
import random
import os
import requests
import sys
import crayons

from pyquery import PyQuery as pq
from requests.exceptions import ConnectionError
from requests.exceptions import SSLError

# Handle imports from Python 2 and 3
if sys.version < '3':
import codecs
from urllib import quote as url_quote
from urllib import getproxies

# Handle Unicode
def u(x):
return codecs.unicode_escape_decode(x)[0]
else:
from urllib.request import getproxies
from urllib.parse import quote as url_quote

def u(x):
return x

if os.getenv('SYNONYM_DISABLE_SSL'): # Set http instead of https
SEARCH_URL = 'http://www.thesaurus.com/browse/{0}?s=t'
VERIFY_SSL_CERTIFICATE = False
else:
SEARCH_URL = 'https://www.thesaurus.com/browse/{0}?s=t'
VERIFY_SSL_CERTIFICATE = True

URL = 'www.thesaurus.com'

USER_AGENTS = ('Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20100101 Firefox/11.0',
'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100 101 Firefox/22.0',
'Mozilla/5.0 (Windows NT 6.1; rv:11.0) Gecko/20100101 Firefox/11.0',
('Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.5 (KHTML, like Gecko) '
'Chrome/19.0.1084.46 Safari/536.5'),
('Mozilla/5.0 (Windows; Windows NT 6.1) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.46'
'Safari/536.5'), )


def get_proxies():
proxies = getproxies()
filtered_proxies = {}
for key, value in proxies.items():
if key.startswith('http'):
if not value.startswith('http'):
filtered_proxies[key] = 'http://%s' % value
else:
filtered_proxies[key] = value
return filtered_proxies


def _get_result(url):
try:
return requests.get(url, headers={'User-Agent': random.choice(USER_AGENTS)}, proxies=get_proxies(),
verify=VERIFY_SSL_CERTIFICATE).text
except requests.exceptions.SSLError as e:
print('[ERROR] Encountered an SSL Error. Try using HTTP instead of '
'HTTPS by setting the environment variable "SYNONYM_DISABLE_SSL".\n')
raise e


def _get_link(query):
return SEARCH_URL.format(query)


def _get_answer(args, link):
page = _get_result(link)
html = pq(page)
all_answers = html('.filters')

if len(all_answers) == 0:
syn_answers = crayons.red(
'\nCannot find synonym for "{}".\n'.format(args['query'][0])
)
return syn_answers

if len(all_answers) == 1:
answer = all_answers.eq(0)
prop = answer('.synonym-description').find('.txt').text()
defn = answer('.synonym-description').find('.ttl').text()
if not (prop or defn):
guess = answer('.heading-row').find('a')
guess_word = guess.text()
syn_answers = crayons.red(
'\nCannot find synonym for "{}". Try "{}"?\n'.format(args['query'][0], guess_word)
)
return syn_answers

import ast
syn_answers = []
index = 0
for answer in all_answers.items():
prop = answer('.synonym-description').find('.txt').text()
defn = answer('.synonym-description').find('.ttl').text()

syn_answers.append((prop, defn, {}))
syn_list = answer('a')
for syn in syn_list.items():
relevancy_str = syn.attr['data-category']
relevancy_dict = ast.literal_eval(relevancy_str)
relevancy_lv = relevancy_dict['name']

if relevancy_lv not in syn_answers[index][2]:
syn_answers[index][2][relevancy_lv] = [syn('.text').text()]
else:
syn_answers[index][2][relevancy_lv].append(syn('.text').text())
index += 1

return syn_answers


def _filter_answer(args):
answer_url = _get_link(args['query'][0])
all_answers = _get_answer(args, answer_url)

if type(all_answers) in [str, crayons.ColoredString]:
return all_answers

if not args['property']:
return all_answers

filter_answer = []
if args['property'] == 'n':
for answer in all_answers:
if answer[0] == 'noun':
filter_answer.append(answer)
if args['property'] == 'v':
for answer in all_answers:
if answer[0] == 'verb':
filter_answer.append(answer)
if args['property'] == 'adj':
for answer in all_answers:
if answer[0] == 'adj':
filter_answer.append(answer)
if args['property'] == 'adv':
for answer in all_answers:
if answer[0] == 'adv':
filter_answer.append(answer)

if not filter_answer:
return crayons.magenta(
'\nIt seems, "{}" has no such property.\n'.format(args['query'][0])
)

return filter_answer


def _display_answer(args):
answer_url = _get_link(args['query'][0])
answers = _filter_answer(args)

if type(answers) in [str, crayons.ColoredString]:
return answers

texts = ''
texts += crayons.green(
'--- Synonyms for "{}" ---\n\n'.format(args['query'][0])
)
for answer in answers:
texts += crayons.red('=== {}. {} ===\n\n'.format(answer[0], answer[1]))
if len(answer[2]) == 0:
texts += crayons.magenta(
'Whoops-a-daisy, no synonyms for {} found.'.format(args['query'][0])
)
elif len(answer[2]) == 1:
(k, v), = answer[2].items()
texts += ', '.join(v)
texts += '\n\n'
else:
if 'relevant-3' in answer[2]:
texts += crayons.green('Most relevant synonyms:\n')
texts += ', '.join(answer[2]['relevant-3'])
texts += crayons.green('\n\nLess relevant synonyms:\n')
if 'relevant-2' in answer[2]:
texts += ', '.join(answer[2]['relevant-2'])
else:
texts += ', '.join(answer[2]['relevant-1'])
texts += '\n\n'
else:
texts += ', '.join(answer[2]['relevant-2'])
texts += '\n\n'

texts += crayons.green('---\nAnswer from {}'.format(answer_url))
return texts


def get_parser():
parser = argparse.ArgumentParser(description='instant synonym answers via command line')
parser.add_argument('query', metavar='Word of Interest', type=str, nargs=1, help='The word of interest')
parser.add_argument('-p', '--property', help='The property of interest (type n / v / adj / adv)',
type=str, choices=['n', 'v', 'adj', 'adv'])
return parser


def synonym(args):
try:
return _display_answer(args)
except (ConnectionError, SSLError):
return 'Failed to establish network connection.\n'


def command_line_runner():
parser = get_parser()
args = vars(parser.parse_args())

if not args['query']:
parser.print_help
return

if sys.version < '3':
print(synonym(args).encode('utf-8', 'ignore'))
else:
print(synonym(args))


if __name__ == '__main__':
command_line_runner()
3 changes: 0 additions & 3 deletions tests/__init__.py

This file was deleted.

34 changes: 0 additions & 34 deletions tests/test_synonym.py

This file was deleted.

0 comments on commit 14f31a2

Please sign in to comment.