Initial commit
This commit is contained in:
commit
ae0d4e01d7
14
.gitignore
vendored
Normal file
14
.gitignore
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
/.bundle/
|
||||
/.yardoc
|
||||
/Gemfile.lock
|
||||
/_yardoc/
|
||||
/coverage/
|
||||
/doc/
|
||||
/pkg/
|
||||
/spec/reports/
|
||||
/tmp/
|
||||
|
||||
.rspec_status
|
||||
.byebug_history
|
||||
|
||||
*.gem
|
5
.travis.yml
Normal file
5
.travis.yml
Normal file
@ -0,0 +1,5 @@
|
||||
sudo: false
|
||||
language: ruby
|
||||
rvm:
|
||||
- 2.4.1
|
||||
before_install: gem install bundler -v 1.15.3
|
6
Gemfile
Normal file
6
Gemfile
Normal file
@ -0,0 +1,6 @@
|
||||
source "https://rubygems.org"
|
||||
|
||||
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
|
||||
|
||||
# Specify your gem's dependencies in thes.gemspec
|
||||
gemspec
|
21
LICENSE.txt
Normal file
21
LICENSE.txt
Normal file
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Rob Watson
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
89
README.md
Normal file
89
README.md
Normal file
@ -0,0 +1,89 @@
|
||||
# thes
|
||||
|
||||
A simple utility to provide access to [thesaurus.com](http://www.thesaurus.com) from the command line.
|
||||
|
||||
## Installation
|
||||
|
||||
`gem install thes`
|
||||
|
||||
## Usage
|
||||
|
||||
`thes <some word>`
|
||||
|
||||
For example:
|
||||
|
||||
`thes nature`
|
||||
|
||||
Result:
|
||||
|
||||
```
|
||||
+--------------------------+-------------------------+-------------------------+
|
||||
| noun: character, disposition |
|
||||
+--------------------------+-------------------------+-------------------------+
|
||||
| description | attributes | bottom line |
|
||||
| essence | being | name of game |
|
||||
| humor | complexion | name of tune |
|
||||
| mood | constitution | nature of beast |
|
||||
| personality | drift | |
|
||||
| quality | essentiality | |
|
||||
| type | features | |
|
||||
| | heart | |
|
||||
| | individualism | |
|
||||
| | individuality | |
|
||||
| | like | |
|
||||
| | makeup | |
|
||||
| | meat | |
|
||||
| | outlook | |
|
||||
| | point | |
|
||||
| | score | |
|
||||
| | stuff | |
|
||||
| | temper | |
|
||||
| | temperament | |
|
||||
| | texture | |
|
||||
| | traits | |
|
||||
+--------------------------+-------------------------+-------------------------+
|
||||
+---------------------------------------+--------------------------------------+
|
||||
| noun: type, kind |
|
||||
+---------------------------------------+--------------------------------------+
|
||||
| character | anatomy |
|
||||
| description | brand |
|
||||
| sort | cast |
|
||||
| structure | category |
|
||||
| style | color |
|
||||
| variety | conformation |
|
||||
| way | figure |
|
||||
| | framework |
|
||||
| | ilk |
|
||||
| | shape |
|
||||
| | species |
|
||||
| | stripe |
|
||||
+---------------------------------------+--------------------------------------+
|
||||
+--------------------------+-------------------------+-------------------------+
|
||||
| noun: earth, creation |
|
||||
+--------------------------+-------------------------+-------------------------+
|
||||
| environment | cosmos | megacosm |
|
||||
| landscape | country | natural history |
|
||||
| view | countryside | |
|
||||
| world | forest | |
|
||||
| | generation | |
|
||||
| | macrocosm | |
|
||||
| | outdoors | |
|
||||
| | scenery | |
|
||||
| | seascape | |
|
||||
| | setting | |
|
||||
| | universe | |
|
||||
+--------------------------+-------------------------+-------------------------+
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
Bug reports and PRs are welcome.
|
||||
|
||||
## License
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
6
Rakefile
Normal file
6
Rakefile
Normal file
@ -0,0 +1,6 @@
|
||||
require "bundler/gem_tasks"
|
||||
require "rspec/core/rake_task"
|
||||
|
||||
RSpec::Core::RakeTask.new(:spec)
|
||||
|
||||
task :default => :spec
|
14
bin/console
Executable file
14
bin/console
Executable file
@ -0,0 +1,14 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require "bundler/setup"
|
||||
require "thes"
|
||||
|
||||
# You can add fixtures and/or initialization code here to make experimenting
|
||||
# with your gem easier. You can also use a different console, if you like.
|
||||
|
||||
# (If you use this, don't forget to add pry to your Gemfile!)
|
||||
# require "pry"
|
||||
# Pry.start
|
||||
|
||||
require "irb"
|
||||
IRB.start(__FILE__)
|
8
bin/setup
Executable file
8
bin/setup
Executable file
@ -0,0 +1,8 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
IFS=$'\n\t'
|
||||
set -vx
|
||||
|
||||
bundle install
|
||||
|
||||
# Do any other automated setup that you need to do here
|
20
exe/thes
Executable file
20
exe/thes
Executable file
@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env ruby
|
||||
|
||||
require 'thes'
|
||||
|
||||
query = ARGV.join(' ').strip
|
||||
|
||||
if query.length.zero?
|
||||
puts 'Usage: thes <search term>'
|
||||
exit 1
|
||||
end
|
||||
|
||||
result = Thes.new(query).call
|
||||
|
||||
if $stdout.isatty
|
||||
IO.popen('less', 'w') { |f| f << result }
|
||||
else
|
||||
$stdout << result
|
||||
end
|
||||
|
||||
exit 0
|
49
lib/thes.rb
Normal file
49
lib/thes.rb
Normal file
@ -0,0 +1,49 @@
|
||||
require "thes/version"
|
||||
|
||||
require 'uri'
|
||||
require 'cgi'
|
||||
require 'open-uri'
|
||||
require 'nokogiri'
|
||||
require 'terminal-table'
|
||||
|
||||
class Thes
|
||||
BASE_URL = 'http://www.thesaurus.com/browse/'.freeze
|
||||
|
||||
def initialize(query)
|
||||
@query = query
|
||||
end
|
||||
|
||||
def call
|
||||
url = URI.join(BASE_URL, CGI.escape(@query))
|
||||
html = Nokogiri::HTML.parse(open(url))
|
||||
filters = html.search('.filters')
|
||||
|
||||
tables = filters.map do |filter|
|
||||
type = filter.search('em.txt').text
|
||||
desc = filter.search('em.txt ~ strong').text
|
||||
|
||||
groups = filter.search('.relevancy-block ul > li > a').group_by do |el|
|
||||
el.attr('data-category').match(/relevant-(\d+)/)[1].to_i
|
||||
end
|
||||
|
||||
columns = groups.values.map do |els|
|
||||
els.map { |el| el.search('span.text').text }
|
||||
end
|
||||
|
||||
columns.each(&:sort!)
|
||||
|
||||
max_size = columns.max_by(&:size).size
|
||||
columns.each { |group| group.fill('', group.size, max_size - group.size) }
|
||||
|
||||
rows = columns.transpose
|
||||
|
||||
Terminal::Table.new(
|
||||
title: "#{type}: #{desc}",
|
||||
rows: rows,
|
||||
style: { width: 80 }
|
||||
)
|
||||
end
|
||||
|
||||
tables.join("\n")
|
||||
end
|
||||
end
|
3
lib/thes/version.rb
Normal file
3
lib/thes/version.rb
Normal file
@ -0,0 +1,3 @@
|
||||
class Thes
|
||||
VERSION = "0.1.0"
|
||||
end
|
2486
spec/pages/nature.html
Normal file
2486
spec/pages/nature.html
Normal file
File diff suppressed because one or more lines are too long
15
spec/spec_helper.rb
Normal file
15
spec/spec_helper.rb
Normal file
@ -0,0 +1,15 @@
|
||||
require "bundler/setup"
|
||||
require "thes"
|
||||
require 'byebug'
|
||||
|
||||
RSpec.configure do |config|
|
||||
# Enable flags like --only-failures and --next-failure
|
||||
config.example_status_persistence_file_path = ".rspec_status"
|
||||
|
||||
# Disable RSpec exposing methods globally on `Module` and `main`
|
||||
config.disable_monkey_patching!
|
||||
|
||||
config.expect_with :rspec do |c|
|
||||
c.syntax = :expect
|
||||
end
|
||||
end
|
31
spec/thes_spec.rb
Normal file
31
spec/thes_spec.rb
Normal file
@ -0,0 +1,31 @@
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe Thes do
|
||||
let(:nature_html) { File.read('spec/pages/nature.html') }
|
||||
|
||||
before {
|
||||
allow(thes).to receive(:open).and_return(nature_html)
|
||||
}
|
||||
|
||||
let(:thes) { Thes.new('nature') }
|
||||
|
||||
subject { thes.call }
|
||||
|
||||
it { is_expected.to include('description') }
|
||||
it { is_expected.to include('essence') }
|
||||
it { is_expected.to include('humor') }
|
||||
it { is_expected.to include('attributes') }
|
||||
it { is_expected.to include('being') }
|
||||
it { is_expected.to include('complexion') }
|
||||
it { is_expected.to include('bottom line') }
|
||||
it { is_expected.to include('name of game') }
|
||||
it { is_expected.to include('name of tune') }
|
||||
it { is_expected.to include('nature of beast') }
|
||||
|
||||
it { is_expected.to include 'megacosm' }
|
||||
it { is_expected.to include 'natural history' }
|
||||
|
||||
it { is_expected.to include 'noun: character, disposition' }
|
||||
it { is_expected.to include 'noun: type, kind' }
|
||||
it { is_expected.to include 'noun: earth, creation' }
|
||||
end
|
31
thes.gemspec
Normal file
31
thes.gemspec
Normal file
@ -0,0 +1,31 @@
|
||||
# coding: utf-8
|
||||
lib = File.expand_path('../lib', __FILE__)
|
||||
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
||||
require 'thes/version'
|
||||
|
||||
Gem::Specification.new do |spec|
|
||||
spec.name = 'thes'
|
||||
spec.version = Thes::VERSION
|
||||
spec.authors = ['Rob Watson']
|
||||
spec.email = ['rob@rfwatson.net']
|
||||
|
||||
spec.summary = %q{Access www.thesaurus.com from the command line.}
|
||||
spec.homepage = 'https://github.com/rfwatson/thes'
|
||||
spec.license = 'MIT'
|
||||
|
||||
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
||||
f.match(%r{^(test|spec|features)/})
|
||||
end
|
||||
spec.bindir = 'exe'
|
||||
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
||||
spec.require_paths = ['lib']
|
||||
|
||||
spec.add_development_dependency 'bundler', '~> 1.15'
|
||||
spec.add_development_dependency 'rake', '~> 10.0'
|
||||
spec.add_development_dependency 'rspec', '~> 3.0'
|
||||
spec.add_development_dependency 'awesome_print', '~> 1.7'
|
||||
spec.add_development_dependency 'byebug', '~> 9'
|
||||
|
||||
spec.add_dependency 'nokogiri', '~> 1.8'
|
||||
spec.add_dependency 'terminal-table', '~> 1.8'
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user